Django 2.0路由變化
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
注意:
-
要捕獲一段url中的值,需要使用尖括號,而不是之前的圓括號;
-
可以轉換捕獲到的值為指定類型,比如例子中的int。默認情況下,捕獲到的結果保存為字符串類型,不包含/這個特殊字符;
-
匹配模式的最開頭不需要添加/,因為默認情況下,每個url都帶一個最前面的/,既然大家都有的部分,就不用浪費時間特別寫一個了。
匹配例子:
-
/articles/2005/03/ 將匹配第三條,並調用views.month_archive(request, year=2005, month=3);
-
/articles/2003/匹配第一條,並調用views.special_case_2003(request);
-
/articles/2003將一條都匹配不上,因為它最后少了一個斜杠,而列表中的所有模式中都以斜杠結尾;
-
/articles/2003/03/building-a-django-site/ 將匹配最后一個,並調用views.article_detail(request,
year=2003, month=3, slug="building-a-django-site"
2.0中使用1.0的url
Django2.0的url雖然改‘配置’了,但它依然向老版本兼容。而這個兼容的辦法,就是用re_path()方法代替path()方法。re_path()方法在骨子里,根本就是以前的url()方法,只不過導入的位置變了。下面是一個例子,對比一下Django1.11時代的語法,有什么太大的差別?
from django.urls import path, re_path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
re_path('articles/(?P<year>[0-9]{4})/', views.year_archive),
re_path('articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/', views.month_archive),
re_path('articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-_]+)/', views.article_detail),
]
與path()方法不同的在於兩點:
- year中匹配不到10000等非四位數字,這是正則表達式決定的
- 傳遞給視圖的所有參數都是字符串類型。而不像path()方法中可以指定轉換成某種類型。在視圖中接收參數時一定要小心。
1.0視圖函數
urlpatterns = patterns('',
(r'^hello/$', **views.hello** ),
(r'^time/$', **views.current_datetime** ),
(r'^time/plus/(d{1,2})/$', **views.hours_ahead** ),
)
# 你可以傳入一個包含模塊名和函數名的字符串,而不是函數對象本身。
urlpatterns = patterns('',
(r'^hello/$', **'mysite.views.hello'** ),
(r'^time/$', **'mysite.views.current_datetime'** ),
(r'^time/plus/(d{1,2})/$', **'mysite.views.hours_ahead'** ),
)
#可以把公共的前綴提取出來,作為第一個參數傳給patterns函數。
from django.conf.urls.defaults import *
urlpatterns = patterns(**'mysite.views'** ,
(r'^hello/$', **'hello'** ),
(r'^time/$', **'current_datetime'** ),
(r'^time/plus/(d{1,2})/$', **'hours_ahead'** ),
)
#使用多個視圖前綴
from django.conf.urls.defaults import *
urlpatterns = patterns('mysite.views',
(r'^hello/$', 'hello'),
(r'^time/$', 'current_datetime'),
(r'^time/plus/(\d{1,2})/$', 'hours_ahead'),
)
urlpatterns += patterns('weblog.views',
(r'^tag/(\w+)/$', 'tag'),
)
#傳遞位置參數
urlpatterns = patterns('',
(r'^articles/(\d{4})/$', views.year_archive),
(r'^articles/(\d{4})/(\d{2})/$', views.month_archive),
)
#傳遞命名參數
urlpatterns = patterns('',
(r'^articles/(?P<year>\d{4})/$', views.year_archive),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', views.month_archive),
)
#以字典的形式傳遞額外的參數,額外的參數和命名參數對於視圖函數來說是一樣的(他不管這個參數是來自請求里的還是額外提供的)
urlpatterns = patterns('',
(r'^foo/$', views.foobar_view, {'template_name': 'template1.html'}),
(r'^bar/$', views.foobar_view, {'template_name': 'template2.html'}),
)
from django.shortcuts import render_to_response
from mysite.models import MyModel
def foobar_view(request, template_name):
m_list = MyModel.objects.filter(is_new=True)
return render_to_response(template_name, {'m_list': m_list})
#額外參數優先於捕捉的命名參數
urlpatterns = patterns('',
(r'^mydata/(?P<id>\d+)/$', views.my_view, {'id': 3}),
)
這里,正則表達式和額外字典都包含了一個 id 。硬編碼的(額外字典的) id 將優先使用。 就是說任何請求(比如, /mydata/2/ 或者 /mydata/432432/ )都會作 id 設置為 3 對待,不管URL里面能捕捉到什么樣的值。
#可以給一個視圖指定默認的參數。 這樣,當沒有給這個參數賦值的時候將會使用默認的值。
urlpatterns = patterns('',
(r'^blog/$', views.page),
(r'^blog/page(?P<num>\d+)/$', views.page),
)
views.py
def page(request, num='1'):
# Output the appropriate page of blog entries, according to num.
# ...
#盡管 \d{4} 將只匹配整數的字符串,但是參數 year 是作為字符串傳至 views.year_archive() 的,而不是整型。
(r'^articles/(?P<year>\d{4})/$', views.year_archive),
在解析URLconf時,請求方法(例如, POST , GET , HEAD )並 不會 被考慮。 換而言之,對於相同的URL的所有請求方法將被導向到相同的函數中。 因此根據請求方法來處理分支是視圖函數的責任。
如果你在函數定義時,只在參數前面加一個*號,所有傳遞給函數的參數將會保存為一個元組. 如果你在函數定義時,在參數前面加兩個*號,所有傳遞給函數的關鍵字參數,將會保存為一個字典。
#URLconf都可以包含其他URLconf模塊
#例子中的指向 include() 的正則表達式並 不 包含一個 $ (字符串結尾匹配符),但是包含了一個斜桿。 每當Django遇到 include() 時,它將截斷匹配的URL,並把剩余的字符串發往包含的URLconf作進一步處理。
urlpatterns = patterns('',
(r'^weblog/', include('mysite.blog.urls')),
(r'^photos/', include('mysite.photos.urls')),
(r'^about/$', 'mysite.views.about'),
)
