schema://host[:port#]/path/.../?query-stringpython
url(r'^test1/9999/$', views.test1.as_view()), #普通用法 url(r'^test2/([0-9]{4})/$', views.test2.as_view()), # 單個非命名參數 url(r'^test3/([0-9]{4})/([0-9]{2})/$', views.test3.as_view()), url(r'^test4/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.test4.as_view()),
咱們先開始建一個django工程 在這裏咱們給給工程命名爲lesson1 放在Django_lesson文件夾下
具體建django工程的細節詳情見Django-0一、初識Django和搭建Django helloworld正則表達式
而後新建一個app 名爲urltestdjango
在lesson1.url.py 中導入viewsegmentfault
from urltest import views
在lesson.urls.py中添加如下路由瀏覽器
url(r'^admin/', admin.site.urls), url(r'^test1/9999/$', views.Test1.as_view()), url(r'^test2/([0-9]{4})/$', views.Test2.as_view()), url(r'^test3/([0-9]{4})/([0-9]{2})/$', views.Test3.as_view()), views.Test4.as_view()),
在urltest.view.py中添加如下視圖類服務器
class Test1(View): def get(self, request): msg = "Test1 sucessful" return HttpResponse(msg) class Test2(View): def get(self, request, year): msg = "Test2 sucessful %s 年" % year return HttpResponse(msg) class Test3(View): def get(self, request, year, month): msg = "Test3 sucessful %s 年 %s 月" % (year, month) return HttpResponse(msg)
注:
若要從URL 中捕獲一個值,只須要在它周圍放置一對圓括號。
不須要添加一個前導的反斜槓,由於每一個URL 都有。例如,應該是^articles 而不是 ^/articles。
每一個正則表達式前面的'r' 是可選的可是建議加上。它告訴Python 這個字符串是「原始的」 —— 字符串中任何字符都不該該轉義。參見Dive Into Python 中的解釋。app
^表明開始匹配,若是隻有^符號,則只須要部分匹配成功便可
$表明結束匹配,添加$符號, 通常就表明完整匹配less
咱們的URL匹配規則必定須要保持惟一函數
上面的示例使用簡單的、沒有命名的正則表達式組(經過圓括號)來捕獲URL 中的值並以位置 參數傳遞給視圖。在更高級的用法中,可使用命名的正則表達式組來捕獲URL 中的值並以關鍵字 參數傳遞給視圖。
在Python 正則表達式中,命名正則表達式組的語法是(?P<name>pattern)
,其中name 是組的名稱,pattern 是要匹配的模式。工具
url(r'^test4/(?P<year>[0-9]{4})/$', views.Test4.as_view()), url(r'^test5/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.Test5.as_view()),
在urltest.view.py中添加如下視圖類
class Test4(View): def get(self, request, year): msg = "Test3 sucessful %s 年" % year return HttpResponse(msg) class Test5(View): def get(self, request, month, year): # 這裏咱們交換了year和month的順序 msg = "Test3 sucessful %s 年 %s 月" % (year, month) return HttpResponse(msg)
若是有命名參數,則使用這些命名參數,忽略非命名參數。
不然,它將以位置參數傳遞全部的非命名參數。
請求的URL被看作是一個普通的Python 字符串, URLconf在其上查找並匹配。進行匹配時將不包括GET或POST請求方式的參數以及域名。換句話講,全部的請求方法 —— 即,對同一個URL的不管是POST請求、GET請求、或HEAD請求方法等等 —— 都將路由到相同的函數。
每一個捕獲的參數都做爲一個普通的Python 字符串傳遞給視圖,不管正則表達式使用的是什麼匹配方式。
在任什麼時候候,你的urlpatterns 均可以包含其它URLconf 模塊。這實際上將一部分URL 放置於其它URL 下面。
在lesson1.urls.py中加入如下代碼
from django.conf.urls import include # 導入 include url(r'^test7/', include('urltest.urls')), # 加入路由
在urltest文件夾下新建urls.py加入如下代碼
from django.conf.urls import url from urltest import views urlpatterns = [ url(r'^test7/$', views.Test7.as_view()), ]
在urltest.views.py加入如下視圖類
class Test7(View): def get(self, request): # 這裏咱們交換了year和month的順序 msg = "Test7 sucessful" return HttpResponse(msg)
URLconfs 具備一個鉤子,讓你傳遞一個Python 字典做爲額外的參數傳遞給視圖函數。
django.conf.urls.url() 函數能夠接收一個可選的第三個參數,它是一個字典,表示想要傳遞給視圖函數的額外關鍵字參數。
#lesson1.urls.py中加入這個路由 url(r'^test8/', include('urltest.urls'), {'name': 'lethe', 'date': '2018'}), #urltest.urls.py中加入這個路由 url(r'^test8/$', views.Test8.as_view()), #views.py中加入這個視圖類 class Test8(View): def get(self, request, name, date): # 這裏咱們交換了year和month的順序 msg = "Test8 sucessful by %s in %s" % (name, date) return HttpResponse(msg)
當Django 找不到一個匹配請求的URL 的正則表達式時,或者當拋出一個異常時,Django 將調用一個錯誤處理視圖。
Http狀態碼
每個請求,都會返回一個狀態
200 : 請求正常
404:找不到頁面
403:是指服務器拒絕
400:request異常
500:服務器異常
在URLconf中指定參數,這些參數分別是
handler404
一個callable或一個字符串,表示若是沒有URL模式匹配,應該調用的視圖的完整Python導入路徑。
默認狀況下是'django.views.defaults.page_not_found'。
handler500
一個callable或一個字符串,表示若是沒有URL模式匹配,應該調用的視圖的完整Python導入路徑。
默認狀況下,這是'django.views.defaults.page_not_found'。
handler403
一個callable或一個字符串,表示若是用戶沒有訪問資源所需的權限,應調用的視圖的完整Python導入路徑。
默認狀況下,這是'django.views.defaults.permission_denied'。
handler400
若是HTTP客戶端已發送致使錯誤條件的請求和狀態代碼爲400的響應,則應調用的可調用或表示完整的Python視圖導入路徑的字符串。
默認狀況下,這是'django.views.defaults.bad_request'。
在settings.py中將DEBUG值改成True
當找不到頁面的時候 頁面顯示以下圖
而後咱們再在settings.py中將DEBUG值改成False (咱們通常在開發的時候設置DEBUG值爲True 在產品上線的時候將DEBUG值改成False)
當找不到頁面的時候 頁面顯示以下圖
咱們將代碼做以下更改
#在views.py中加入如下代碼 def Error404(request): return HttpResponse("哎呦 404 尷尬了!") #DEBUG值保持爲False #在lesson1.py中加入 handler404 = 'urltest.views.Error404'
在使用Django 項目時,一個常見的需求是得到URL 的最終形式,以用於嵌入到生成的內容中(視圖中和顯示給用戶的URL等)或者用於處理服務器端的導航(重定向等)。
人們強烈但願不要硬編碼這些URL(費力、不可擴展且容易產生錯誤)或者設計一種與URLconf 絕不相關的專門的URL 生成機制,由於這樣容易致使必定程度上產生過時的URL。
換句話講,須要的是一個DRY 機制。除了其它優勢,它還容許設計的URL 能夠自動更新而不用遍歷項目的源代碼來搜索並替換過時的URL。
要獲取一個URL,最初擁有的信息是負責處理它的視圖的標識(例如名字),與查找正確的URL 的其它必要的信息如視圖參數的類型(位置參數、關鍵字參數)和值。
Django 提供了一個解決方案使得URL 映射是URL 設計惟一的儲存庫。你用你的URLconf填充它,而後能夠雙向使用它:
根據用戶/瀏覽器發起的URL 請求,它調用正確的Django 視圖,並從URL 中提取它的參數須要的值。
根據Django 視圖的標識和將要傳遞給它的參數的值,獲取與之關聯的URL。
第一種方式是咱們在前面的章節中一直討論的用法。第二種方式叫作反向解析URL、反向URL匹配、反向URL查詢或者簡單的URL反查。
在須要URL 的地方,對於不一樣層級,Django 提供不一樣的工具用於URL 反查:
在模板中:使用url 模板標籤。
在Python 代碼中:使用django.core.urlresolvers.reverse() 函數。
在更高層的與處理Django 模型實例相關的代碼中:使用get_absolute_url() 方法。
#在urls.views.py中加入如下代碼 url(r'^articles/$', views.Articles.as_view()), #在views.py中加入如下代碼 class Articles(View): def get(self, request): return redirect('/test1/9999/')
URL 命名空間容許你反查到惟一的命名URL 模式,即便不一樣的應用使用相同的URL 名稱。第三方應用始終使用帶命名空間的URL 是一個很好的實踐(咱們在教程中也是這麼作的)。相似地,它還容許你在一個應用有多個實例部署的狀況下反查URL。換句話講,由於一個應用的多個實例共享相同的命名URL,命名空間提供了一種區分這些命名URL 的方法。
一個URL命名空間有兩個部分,它們都是字符串:
應用命名空間
它表示正在部署的應用的名稱。一個應用的每一個實例具備相同的應用命名空間。例如,能夠預見Django 的管理站點的應用命名空間是'admin'。
實例命名空間
它表示應用的一個特定的實例。實例的命名空間在你的所有項目中應該是惟一的。可是,一個實例的命名空間能夠和應用的命名空間相同。它用於表示一個應用的默認實例。
URL 的命名空間使用':' 操做符指定。例如,管理站點應用的主頁使用'admin:index'。它表示'admin' 的一個命名空間和'index' 的一個命名URL。
命名空間也能夠嵌套。命名URL'sports:polls:index' 將在命名空間'polls'中查找'index',而poll 定義在頂層的命名空間'sports' 中。
#在lesson1.urls.py中加入如下路由 url(r'^url1test/', include('urltest.urls_1', namespace='url1test')), url(r'^url2test/', include('urltest.urls', namespace='url2test')), url(r'^url1_login/$', views.ToUrl1Login.as_view()), url(r'^url2_login/$', views.ToUrl2Login.as_view()), #在urltest文件夾下新建url_1.py並加入如下代碼 from django.conf.urls import url from urltest import views urlpatterns = [ url(r'^login/$', views.Url1Login.as_view(), name='login'), ] #在urltest.url.py中加入如下路由 url(r'^login/$', views.Url2Login.as_view(), name='login'), # 在views.py中加入如下視圖類 class Url1Login(View): def get(self, request): return HttpResponse("我是url1test.login") class Url2Login(View): def get(self, request): return HttpResponse("我是url2test.login") class ToUrl1Login(View): def get(self, request): return redirect(reverse('url1test:login')) class ToUrl2Login(View): def get(self, request): return redirect(reverse('url2test:login'))
當輸入/url1_login/時 跳到ToUrl1Login而後跳到url1test:login(即namespace='url1test',name='login'的路由 即/url1test/login/ 打印我是url1test.login)
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.shortcuts import render from django.views import View from django.http import HttpResponse from django.shortcuts import reverse, redirect # Create your views here. class Test1(View): def get(self, request): msg = "Test1 sucessful" return HttpResponse(msg) class Test2(View): def get(self, request, year): msg = "Test2 sucessful %s 年" % year return HttpResponse(msg) class Test3(View): def get(self, request, year, month): msg = "Test3 sucessful %s 年 %s 月" % (year, month) return HttpResponse(msg) class Test4(View): def get(self, request, year): msg = "Test4 sucessful %s 年" % year return HttpResponse(msg) class Test5(View): def get(self, request, month, year): # 這裏咱們交換了year和month的順序 msg = "Test5 sucessful %s 年 %s 月" % (year, month) return HttpResponse(msg) class Test6(View): def get(self, request, num='1'): # 這裏咱們交換了year和month的順序 msg = "Test6 sucessful num=%s" % num return HttpResponse(msg) class Test7(View): def get(self, request): # 這裏咱們交換了year和month的順序 msg = "Test7 sucessful" return HttpResponse(msg) class Test8(View): def get(self, request, name, date): # 這裏咱們交換了year和month的順序 msg = "Test8 sucessful by %s in %s" % (name, date) return HttpResponse(msg) class Articles(View): def get(self, request): return redirect('/test1/9999/') class Reverse_test(View): def get(self, request): return redirect(reverse('reverse_test', args=('2021',))) class Url1Login(View): def get(self, request): return HttpResponse("我是url1test.login") class Url2Login(View): def get(self, request): return HttpResponse("我是url2test.login") class ToUrl1Login(View): def get(self, request): return redirect(reverse('url1test:login')) class ToUrl2Login(View): def get(self, request): return redirect(reverse('url2test:login')) def Error404(request): return HttpResponse("哎呦 404 尷尬了!")
from django.conf.urls import url, include from django.contrib import admin from urltest import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test1/9999/$', views.Test1.as_view()), url(r'^test2/([0-9]{4})/$', views.Test2.as_view(), name='reverse_test'), url(r'^test3/([0-9]{4})/([0-9]{2})/$', views.Test3.as_view()), url(r'^test4/(?P<year>[0-9]{4})/$', views.Test4.as_view()), url(r'^test5/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.Test5.as_view()), url(r'^test6/(?P<num>[0-9]+)/$', views.Test6.as_view()), url(r'^test7/', include('urltest.urls')), url(r'^test8/', include('urltest.urls'), {'name': 'lethe', 'date': '2018'}), url(r'^articles/$', views.Articles.as_view()), url(r'^reverse/$', views.Reverse_test.as_view()), url(r'^url1test/', include('urltest.urls_1', namespace='url1test')), url(r'^url2test/', include('urltest.urls', namespace='url2test')), url(r'^url1_login/$', views.ToUrl1Login.as_view()), url(r'^url2_login/$', views.ToUrl2Login.as_view()), ] handler404 = 'urltest.views.Error404'
from django.conf.urls import url from urltest import views urlpatterns = [ url(r'^test7/$', views.Test7.as_view()), url(r'^test8/$', views.Test8.as_view()), url(r'^login/$', views.Url2Login.as_view(), name='login'), ]
from django.conf.urls import url from urltest import views urlpatterns = [ url(r'^login/$', views.Url1Login.as_view(), name='login'), ]
注: 本文章是本人的CSDN博客中對應的文章轉過來的