1. 程式人生 > >Django - 路由層

Django - 路由層

目錄

一、簡單路由實現(1.x)

二、無名分組

三、有名分組

四、反向解析:動態更改所有路徑

1、檢視函式內的反向解析:reverser()

2、模板層內的反向解析:{% url "別名" 引數  引數%}

 五、路由分發(1.x):防止一個路由檔案的龐大導致可讀性差

六、名稱空間(namespace):防止重名路由衝突

七、偽靜態:偽裝成靜態網頁,有利於搜尋導航的優先匹配

八、Django - 2.X 和1.X的區別

1、2.0的re_path  用法等同於 1.0的url

2、path :使用精確路徑代替正則匹配

 2-1 轉換器:將url傳入的引數進行對應匹配,將符合匹配的接在url路徑後

 2-2 自定義轉換器

九、專案路由配置小技巧



一、簡單路由實現(1.x)

from django.conf.urls import url
from app01 import views

'''
urlpatterns = [
     url(正則表示式, views檢視函式(末尾通常不加括號),引數[字典形式],別名[可選的name引數]),
]
'''

urlpatterns = [
        url(r'^blog/$', views.blog),
]

二、無名分組

總結:

  • 按位置傳參
  • url分組,以‘/’進行分組,
  • def publish(request,*args):   檢視函式可以這樣接收
  • 不可與有名分組混用
from django.conf.urls import url
from app01 import views

'''
urlpatterns = [
     url(正則表示式(傳入引數), views檢視函式(末尾通常不加括號),引數[字典形式],別名[可選的name引數]),
]
'''

urlpatterns = [
        # 路由後跟四個0-9的數字當做引數傳給檢視函式
        url(r'^blog/([0-9]{4})', views.blog),
        url(r'^publish/([0-9]{4})/([0-9]{2})$', views.publish)
]
# 檢視函式接受引數
def blog(request,year):
    print(year)
    return HttpResponse('ok')

# 按位置接受傳參
def blog(request,*args):
    return HttpResponse('ok')

三、有名分組

總結:

  • 按關鍵字傳參
  • url(r'^publish/(?P<year>[0-9]{4})/(?P<mounth>[0-9]{2})/$', views.publish),
    --- 格式:(?P<name>pattern);
    name:組的名稱; pattern :匹配的模式
  • def publish(request, mounth,year): 檢視函式需要定義形參,形參名字要跟分組的名字對應,與順序無關
  • 不能和無名分組混用
from django.conf.urls import url
from app01 import views

'''
urlpatterns = [
     url(正則表示式(傳入引數), views檢視函式(末尾通常不加括號),引數[字典形式],別名[可選的name引數]),
]
'''

urlpatterns = [
        # 路由後跟四個0-9的數字取名為year當做引數傳給檢視函式
        url(r'^blog/(?P<year>[0-9]{4})', views.blog),
        url(r'^publish/(?P<year>[0-9]{4})/(?P<day>[0-9]{2})$', views.publish)
]
# 檢視函式接受引數
def blog(request,day,year):
    print(year)
    print(day)
    return HttpResponse('ok')

四、反向解析:動態更改所有路徑

1、檢視函式內的反向解析:reverser()

'''
# urls.py檔案內的路由配置 

-1 無引數
url(r'^publishadd133/$', views.publishadd,name='ddd'),
-2 無名分組
url(r'^publishadd/([0-9]{4})/([0-9]{2})/$', views.publishadd,name='ddd'),
-3 有名分組
url(r'^publishadd/(?P<year>[0-9]{4})/(?P<mounth>[0-9]{2})/$', views.publishadd,name='ddd'),
'''

from django.shortcuts import reverse
			
# 無引數
url=reverse('ddd')
# 無名分組
url=reverse('ddd',args=(2018,12,))
# 有名分組
url=reverse('ddd',args=(2018,12,)) 
url=reverse('ddd',kwargs={'year':2018,'mounth':12})

2、模板層內的反向解析:{% url "別名" 引數  引數%}

'''
# urls.py檔案內的路由配置 

-1 無引數
url(r'^publishadd133/$', views.publishadd,name='ddd'),
-2 無名分組
url(r'^publishadd/([0-9]{4})/([0-9]{2})/$', views.publishadd,name='ddd'),
-3 有名分組
url(r'^publishadd/(?P<year>[0-9]{4})/(?P<mounth>[0-9]{2})/$', views.publishadd,name='ddd'),
'''

# 無引數
{% url 'ddd' %}
# 無名分組
{% url 'ddd' 2018 12 %}
# 有名分組
{% url 'ddd' 2018 12 %} 
{% url 'ddd' year=2018 mounth=12 %}

 

 

 五、路由分發(1.x):防止一個路由檔案的龐大導致可讀性差

# 總路由檔案
from django.conf.urls import url,include
urlpatterns = [
    url(r'^app01/',include('app01.urls'))
    url(r'^app02/',include('app02.urls'))
]

''' 注意: 總路由檔案內,不能在正則匹配內新增$結束符 '''
# app資料夾內路由檔案
from django.conf.urls import url
from app02 import views

urlpatterns = [
    url(r'^user/$',view.user)
    url(r'^user_list/$',view.user_list)
]

'''
瀏覽器檢視指定路由:128.0.0.1:8000/app02/user
'''

 

六、名稱空間(namespace):防止重名路由衝突

名稱空間(英語:Namespace)是表示識別符號的可見範圍。
一個識別符號可在多個名稱空間中定義,它在不同名稱空間中的含義是互不相干的。這樣,在一個新的名稱空間中可定義任何識別符號,它們不會與任何已有的識別符號發生衝突,因為已有的定義都處於其它名稱空間中。

由於name沒有作用域,Django在反解URL時,會在專案全域性順序搜尋,當查詢到第一個name指定URL時,立即返回

我們在開發專案時,會經常使用name屬性反解出URL,當不小心在不同的app的urls中定義相同的name時,可能會導致URL反解錯誤,為了避免這種事情發生,引入了名稱空間。

# 匯入include 並且在路由分發的時候設定 namespace
from django.conf.urls import url,include
urlpatterns = [
    url(r'^app00/',include('app00.urls',namespace='app00')),
    url(r'^app01/',include('app01.urls',namespace='app01')),
]
# 檢視函式誒的反向解析
url=reverse('app00:index')
print(url)
url2=reverse('app01:index')
print(url2)

# 模板層內的反向解析
{% url 'app01:test'%}
# <a href="{% url 'app00:index'%}">哈哈</a>

七、偽靜態:偽裝成靜態網頁,有利於搜尋導航的優先匹配

# 路由的書寫
# 有名分組 id匹配一個數字 字串連線.html
url(r'^book/(?P<id>\d+.html)',views.book),

# 路由器的訪問 :http://127.0.0.1:8000/book/4.html

 

八、Django - 2.X 和1.X的區別

1、2.0的re_path  用法等同於 1.0的url

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    # re_path---->原來的url
    # re_path('正則',檢視函式)
    re_path('^test/(?P<year>\d+)',views.re_test),
]

2、path :使用精確路徑代替正則匹配

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    # path傳的第一個引數,不是正則,準確的路徑,不支援正則
    # path('精確路徑/<轉換器:匹配路徑引數>',檢視函式(不支援傳參操作),別名)
    # path('test/<path:year>', views.re_test),
    # path('test/<yyy:year>', views.re_test,name='test'),
    path('test/', views.re_test,),
]

 2-1 轉換器:將url傳入的引數進行對應匹配,將符合匹配的接在url路徑後

  • str,匹配除了路徑分隔符(/)之外的非空字串,這是預設的形式
  • int,匹配正整數,包含0。
  • slug,匹配字母、數字以及橫槓、下劃線組成的字串。
  • uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
  • path,匹配任何非空字串,包含了路徑分隔符(/)

 

 2-2 自定義轉換器

from django.contrib import admin
#匯入自定義轉換器所需的 register_converter
from django.urls import path,register_converter
from app01 import views


# 自定義轉換器
# 1 定義一個類
class MyCon:
    # 寫一個正則表示式
    regex = '[0-9]{4}'

    # 匹配出來的資料,會傳到這裡,retrun回去的,會被檢視函式接收
    def to_python(self, value):
        return value

    # 反向解析用的
    def to_url(self, value):
        return '%04d' % value

#註冊轉換器名: register_converter(自定義類名,'自定義轉換器名') 
register_converter(MyCon,'yyy') 

urlpatterns = [
    path('test/<yyy:year>', views.re_test,name='test'),

]

 

九、專案路由配置小技巧

  • 根路徑配置,即首頁預設指定檢視函式   url(r'^$',views.book)
  • 配置錯誤路徑,即從上至下無匹配路徑之後響應預設檢視函式 url(r'',views.errors)