Django框架-Django路由(urls)系統


Django的路由系統

Django 1.1版本 URLConf官方文檔

URL配置(URLconf)就像Django所支撐網站的目錄。它的本質是URL與要為該URL調用的視圖函數之間的映射表。

我們就是以這種方式告訴Django,遇到哪個URL的時候,要對應執行哪個函數。

一、URLconf配置

基本格式:

from  django.conf.urls  import url

urlpatterns = [

    url(正則表達式,views視圖,參數,別名),
]
參數說明:
  正則表達式:一個正則表達式字符串
  view視圖:一個可調用對象,通常為一個視圖函數
  參數:可選的要傳遞給視圖函數的默認參數【字典新式】
  別名:一個可選的name參數,當動態改路勁時需用到

示例:

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

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

請求的例子:
/articles/2005/3/ 不匹配任何url模式,因為列表中的第三個模式要求月份應該是兩個數字。
/articles/2005/ 將匹配列表中的第一個模式不是第二個,因為模式按順序匹配,第一個會首先測試是否匹配。
/articles/2005/03/ 請求將匹配列表中的第三個模式,django將調用函數views.month_archive(request,'2005','03')

 注意:

Django2.0版本中的路由系統是下面的寫法(官方文檔):

from django.urls import path,re_path

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),
]
注:2.0版本中re_path和1.11版本的url用法一樣。

正則表達式詳解:

1、urlPartterns中元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則不再繼續,誰在上面,就先匹配,會覆蓋下面的。

2、若要從url中捕獲一個值【即可以從url中獲取參數】,只需要在它周圍放置一對圓括號(分組匹配)。

3、不需要添加一個前導的反斜杠,因為每個url都有,例如,應該是^active/而不是^/active/。

4、每個正則表達式前面的r‘’是可選的但建議加上,以防特殊字符未轉義。

補充說明

# 是否開啟URL訪問地址后面不為/跳轉至帶有/的路徑的配置項
APPEND_SLASH=True

Django settings.py配置文件中默認沒有 APPEND_SLASH 這個參數,但 Django 默認這個參數為 APPEND_SLASH = True。 其作用就是自動在網址結尾加'/'。

其效果就是:

我們定義了urls.py:

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

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

訪問 http://www.example.com/blog 時,默認將網址自動轉換為 http://www.example/com/blog/ 。

如果在settings.py中設置了 APPEND_SLASH=False,此時我們再請求 http://www.example.com/blog 時就會提示找不到頁面。

二、無名分組和命名分組

無名分組:就是正則匹配分組,圓括號包起來的部分,未指定別名,匹配完全后,將url中的匹配的括號包起來的值,以位置參數傳遞給視圖函數

url(r'^articles/([0-9]{4})/$', views.year_archive),

# 上面([0-9]{4})就是無名分組,匹配4位數字,當前端url中如輸入
http://127.0.0.1:8000/2016/ 時,2016就是匹配的值,django將會將2016以位置參數傳給后面的視圖函數 def  year_archive(request,2016):pass  以用於業務邏輯

命名分組:就是給分組指定一個別名,python的正則分組命名語法為(?P<name>pattern),其中name是組的命名,pattern是匹配的模式,將url中匹配的部分以,關鍵字參數傳遞給視圖函數。

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

# 如瀏覽器中輸入:http:// 127.0.0.1:8000/articles/2016/,
django 會將匹配的2016以關鍵字分方法傳遞給視圖函數供其調用, def year_archive(request, year = ’2016‘):pass

小結:

1、urlconf匹配時,將url當成一個普通的字符串,不考慮請求方法,ip或域名,僅匹配http://www.baidu.com/index/?wd=python 着色部分。

2、捕獲的參數永遠都是字符串 ,如上面傳遞給視圖函數 views.year_archive()中的year的參數永遠是一個字符串,而不是一個數字類型。

3、視圖函數中可以指定默認值

# urls.py中
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# views.py中,可以為num指定默認值
def page(request, num="1"):
    pass

在上面的例子中,兩個URL模式指向相同的view - views.page - 但是第一個模式並沒有從URL中捕獲任何東西。

如果第一個模式匹配上了,page()函數將使用其默認參數num=“1”,如果第二個模式匹配,page()將使用正則表達式捕獲到的num值。

4、urlconf可以傳遞額外的參數給視圖函數

URLconfs 具有一個鈎子,讓你傳遞一個Python 字典作為額外的參數傳遞給視圖函數。

django.conf.urls.url() 可以接收一個可選的第三個參數,它是一個字典,表示想要傳遞給視圖函數的額外關鍵字參數。

例如:

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

urlpatterns = [
    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

在這個例子中,對於/blog/2005/請求,Django 將調用views.year_archive(request, year='2005', foo='bar')。
當傳遞額外參數的字典中的參數URL中捕獲值的命名關鍵字參數同名時,函數調用時將使用的是字典中的參數,而不是URL中捕獲的參數。

三、Url分發

當多個應用在一個項目里時,需要用到url分發,各app管理自己的url

例如:app01、app02

1、分別在app01和app02下創建自己的urls.py【各應用下與views.py同級目錄中創建】

2、分別配置app的urls.py

app01

from django.conf.urls import url # 導入管理url的模塊

from app01 import views # 導入應用的的views

urlpatterns = [ url(r'^home/[0-9]{4}/[0-9]{2}/$' ,views.app01_home)]

app02 類似

3、在全局urls.py文件中導入app01及app02的urls

1、from django.conf.urls import include

2、在urlpatterns中寫入

url(r'^app01/' ,include('app01.urls')),

url(r'^app02/', include('app02.urls'))

注:此時相當於app01是一級目錄,而app自己的url相當於二級目錄,當訪問時先到全局urls后到應用的urls

相當於進行字符串拼接

如:http://www.baidu.com/app01/home  會先找到app01,再去對應app下的urls中找home的url

四、命名Url和Url反向解析 

官方:Django 提供一個辦法是讓URL 映射是URL 設計唯一的地方。你填充你的URLconf,然后可以雙向使用它:

  • 根據用戶/瀏覽器發起的URL 請求,它調用正確的Django 視圖,並從URL 中提取它的參數需要的值。
  • 根據Django 視圖的標識和將要傳遞給它的參數的值,獲取與之關聯的URL。

第一種方式就是,正向的,我們在瀏覽器種輸入地址,服務器到urls去匹配,然后執行對應的視圖函數。

第二種方式就是,反向解析url,反向url匹配,反向url查詢或簡單的url反查,如我們業務處理中redirect跳轉等。

 

本質為urls.py中的url匹配規則設置別名

作用:解決當需要更新頁面或視圖函數中的url時,無需再一個個去遍歷修改,只需要再urlsconf中即urls.py中修改,視圖和模板就會自動更新url

常規

url(r'show_class/', views.show_class, name='class_list'),

無名分組

url(r'^home/([0-9]{4})/([0-9]{2})/$',views.login ,name='home')

有名分組

url(r'^home/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.login ,name='home')

在views中使用

from django.shortcuts import reverse # 導入反向解析模塊

常規

def test(request):

return redirect(reverse('class_list'))

無名分組

return redirect(reverse('home' , args=('1988','09')))

上面會字符串拼接成:home/1988/09/

命名分組

return redirect(reverse("home", kwargs={"year":2018}))

在模板html中使用

語法:{% url 路徑設置的別名 %}

常規

{% url 'class_list' %}

無名分組

{% url 'home' '2018' '09' %}

有名分組

{% url 'home' '2018' '09' %}

{% url 'home' month='09' year='2018' %}

 

命名空間模式

當多個app的url設置的別名相同時,容易出現異常報錯,在全局urls里后面的覆蓋前面的,故有下面兩個方案解決

1、在url命名前加上應用的名字 如 name = 'app_name.路徑別名'

2、在全局urls.py中導入app01時,為url也進行命名 namespace='別名,一般為應用的名字'

from django.conf.urls import url, include

url( r'app01/ ',include('app01.urls', namespace= 'app01'))

3、在app的views.py視圖函數使用

from django.shorcuts import reverse

def
test(request) return redirect(reverse('app01:home', ))

4、在模板中使用

{% url 'app01:home' %}

 

注:如果app在全局的url指定了namesapce,那么單個app的應用url就必須也指定name,不然無法使用!!!

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM