1. 程式人生 > >005--Django2.0的路由層

005--Django2.0的路由層

URL配置就像Django所支撐的網站目錄,它的本質是每條URL呼叫的檢視函式的對映表,每一個請求執行對應的檢視函式。

1、簡單的路由配置 
 1 from django.contrib import admin
 2 from app01 import views
 3 from django.urls import path, re_path,include
 4 # 與django1版本不同的是django2版本是path和 re_path。re_path支援正則,和django1版本的url一樣的效果。include是路由分發用的。分發給每個app
5
6 urlpatterns = [ 7 path('admin/', admin.site.urls),
00 re_path('^$',views.index)    # 直接寫開頭和結尾兩個匹配字元,代表ip加埠模式
8 re_path(r'^articles/2003/$', views.special_case_2003), # 以article開頭和以2003結尾的都可以匹配的到 9 re_path(r'^articles/([0-9]{4})/$', views.year_archive), # 對應函式接收時,多一個引數 year_archive(request,year)
10 re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), # 對應函式接收時,多兩個引數 month_archive(request,year,month)

注意:若要從URL捕獲一個值,只需要在他周圍放置()。開頭也不需要加/ ,因為每個url都會自動加上。例如^articles,而不是^/articles。每個正則表示式前面的r代表不轉義的意思。告訴python這個字串是原始的,不需要任何轉義。

2、有名分組 

上面的示例中使用簡單的、沒有命名的正則表示式組(通過括號)來捕獲url值,並以位置引數傳遞給檢視。在高階用法中,可以給正則表示式命名。這樣就是以關鍵字引數傳遞給檢視,在python中,命名正則表示式的語法是(?P<name>pattren)

name是組的名稱。pattern是要匹配的模式。

1     # 命名分組
2     re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), #year_archive(request,month=month,year=year)  以關鍵字引數傳遞給檢視,位置可調換。

 

3、路由分發 

 當一個專案有好多條url和好多應用時,就要設計好,運用include路由分發到不同app裡面,這樣看起來也舒服,全寫在主url太多了。

1     # 分發
2     re_path(r'^',include('app01.urls')),
3     re_path(r'^app01/',include('app01.urls')),      # 以app01開頭。然後分發到app01下的urls檔案
4     re_path(r'^app02/',include('app02.urls')),      # 以app01開頭。然後分發到app01下的urls檔案

 

4、反向解析 

 django專案也有用於嵌入到生產內容中、比如檢視和模版裡的url等。或者重定向等。如果你專案之前設計好了url.,專案完成後或者上線後,老闆要求你改url,後面的檢視和模版也要跟著改,實在麻煩,所以有了反向解析。不再採取硬編碼的url。

1     # 反向解析
2     re_path('^login/$', views.login, name='login'),# name代表名稱。

3 re_path(r'^articles/([0-9]{4})/$', views.year_archive,name='y_a'), # 帶引數的url反向解析
 
 
 
 
 
 
 
 
<!--語法{% url 'name' %} name對應urls.py裡的每條url後面的name變數,這樣,就算url規則改了,form表單裡會自動反向解析那條修改的url。-->
<form action="{% url 'login' %}" method="post">
    使用者名稱:<input type="text" name="user">
    密碼:<input type="password" name="pwd">
    <input type="submit" value="登陸">
</form>
<a href="{% url 'y_a' 2012 %}">2012 Archive</a>

<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'y_a' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>
 1 from django.shortcuts import render, HttpResponse,reverse
 2 # django的三種響應方式,render是渲染一個頁面,Httpresponse是返回一個字串,reverse是反向解析
 3 
 4 # Create your views here.
 5 
 6 def special_case_2003(request):
 7 
 8     url=reverse('s_c_2003')
 9     print(url)
00 year=2000
10 print(reverse('y_a',args=(year,))) # 如果要傳遞引數,後面跟元祖, 11 return HttpResponse("Hello Python") 12 13 def index(request): 14 print(reverse('app01:index')) # app01下對應的name是index的url 15 return HttpResponse('app01的index')

 

4、名稱空間 

 名稱空間:namespace,當不小心在不同的app的urls中定義相同的name時,可能會導致URL反解錯誤,為了避免這種事情發生,引入了名稱空間。

    # 名稱空間:include放一個元祖
    re_path(r'^app01/', include(('app01.urls', 'app01'))),
    re_path(r'^app02/', include(('app02.urls', 'app02'))),
 1 app01.urls:
 2 
 3 urlpatterns = [
 4 re_path(r'^index/', views.index,name="index"),
 5 ]
6 app02.urls: 7 8 urlpatterns = [ 9 re_path(r'^index/', views.index,name="index"), 10 ]
 1 app01.views
 2 
 3 from django.core.urlresolvers import reverse
 4 def index(request):
 5   return HttpResponse(reverse("app01:index"))
 6 app02.views
 7 
 8 from django.core.urlresolvers import reverse
 9 def index(request):
10   return HttpResponse(reverse("app02:index"))