Django路由系統

路由的做用

路由即請求地址與視圖函數的映射關係,若是把網站比喻爲一本書,那路由就比如是這本書的目錄,在Django中路由默認配置在urls.py中,以下圖:html

 簡單的路由配置

#urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    #首頁匹配
    url(r'^$',views.home),
    url(r'test', views.test),
    url(r'testadd', views.testadd)
]

"""
url方法第一個參數是一個正則表達式
路由匹配按照正則匹配 一旦正則可以匹配到內容 會馬上執行對應的視圖函數
不會再繼續匹配了,因此完整的正則表達式應該是 r'^test/$'

用戶輸入url不加最後的斜槓 django會默認自動加上    
你能夠在配置文件中指定是否開啓該功能
APPEND_SLASH = True  #自動加斜槓,改成False就不讓它自動加
"""

分組

什麼是分組、爲什麼要分組呢?好比咱們開發了一個博客系統,當咱們須要根據文章的id查看指定文章時,瀏覽器在發送請求時須要向後臺傳遞參數(文章的id號),可使用 http://127.0.0.1:8001/article/?id=3,也能夠直接將參數放到路徑中http://127.0.0.1:8001/article/3/前端

針對後一種方式Django就須要直接從路徑中取出參數,這就用到了正則表達式的分組功能了,其實分組就是給一段正則表達式加括號。分組分爲兩種:無名分組與有名分組python

無名分組

  在路由匹配的時候給某段正則表達式加了括號
  匹配的時候會將括號內正則表達式匹配到的內容當作位置參數傳遞給對應的視圖函數,有幾個分組就傳幾個位置參數正則表達式

urls.py文件django

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

views.py文件後端

def test(request,args):
    #print(args)
    return HttpResponse('test')

有名分組

urls.py文件瀏覽器

# 該正則會匹配url地址的路徑部分爲:article/數字/
# 匹配的時候會將括號內正則表達式匹配到的內容當作關鍵字參數(article_id=匹配成功的數字)傳遞給對應的視圖函數
url(r'^article/(?P<article_id>\d+)/',views.article)

views.py文件app

# 須要額外增長一個形參,形參名必須爲article_id
def article(request,article_id):
    return HttpResponse('id爲 %s 的文章內容...' %article_id)

補充:函數

# 無名有名不能混合使用
# url(r'^test/(\d+)/(?P<year>\d+)/', views.test), #錯誤寫法
# 雖然不能混合使用 可是同一種命名方式 可使用多個url(r'^test/(\d+)/(\d+)/',views.test),
url(r'^article/(?P<xxx>\d+)/(?P<year>\d+)/',views.article),

反向解析

反向解析:給路由與視圖函數的對應關係起一個名字(這個名字在整個項目中不要重複),前端和後端能夠根據這個名字經過一些方法獲得一個結果,這個結果能夠訪問名字所對應的url網站

在軟件開發初期,url地址的路徑設計可能並不完美,後期須要進行調整,若是項目中不少地方使用了該路徑,一旦該路徑發生變化,就意味着全部使用該路徑的地方都須要進行修改,這是一個很是繁瑣的操做。

解決方案就是在編寫一條url時,能夠經過參數name爲url地址的路徑部分起一個別名,項目中就能夠經過別名來獲取這個路徑。之後不管路徑如何變化別名與路徑始終保持一致。

上述方案中經過別名獲取路徑的過程稱爲反向解析。

urls.py

url(r'^testadd/',views.testadd,name='add')  # 路徑testadd/的別名爲add

html文件

{% url 'add' %}

views.py

from django.shortcuts import render,HttpResponse,redirect
from django.shortcuts import reverse #reverse用於反向解析

url = reverse('add')

 無名反向解析

url(r'^aritcle/(\d+)/$',views.article,name='article_page'), # 無名分組

# 針對無名分組,好比咱們要反向解析出:/aritcle/1/ 這種路徑,寫法以下
在views.py中,反向解析的使用:
    url = reverse('article_page',args=(1,)) 
在html文件中,反向解析的使用
    {% url 'article_page' 1 %}

有名反向解析

url(r'^user/(?P<uid>\d+)/$',views.article,name='user_page'), # 有名分組

# 針對有名分組,好比咱們要反向解析出:/user/1/ 這種路徑,寫法以下
在views.py中,反向解析的使用:
    url = reverse('user_page',kwargs={'uid':1}) 
在html文件中,反向解析的使用
    {% url 'user_page' uid=1 %}

路由分發

當django項目比較龐大時,路由與視圖函數對應關係較多,總路由代碼太多冗長,不便於維護管理
因此咱們應該將app本身的路由交由本身管理,總路由再也不作路由與視圖函數的對應關係。而僅僅只作一個分發任務的操做,django支持每一個app均可以有本身的urls.py。

根據請求的不一樣 識別出當前請求須要訪問的功能屬於哪一個app,而後自動下發到對應app裏面的urls.py中。由app裏面的urls.py作路由與視圖函數的匹配

不只如此每一個app除了能夠有本身的urls.py以外,還能夠有本身的static文件夾和templates模板文件,
基於上面的特色,django分小組開發會變得額外的簡單。每一個人只須要開發本身的app便可,以後只須要建立一個空的django項目,將多我的的app所有拷貝項目下,配置文件註冊,總路由分發一次

一、建立兩個app

二、在每一個app下手動建立urls.py來存放本身的路由

app01下的urls.py文件

from django.conf.urls import url
# 導入app01的views
from app01 import views
urlpatterns = [ url(r'^index/',views.index), ]

app01下的views.py

def index(request):
    return HttpResponse('我是app01的index頁面...')

app02下的urls.py文件

from django.conf.urls import url
# 導入app02的views
from app02 import views

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

app02下的views.py

def index(request):
    return HttpResponse('我是app02的index頁面...')

三、在總的urls.py文件中(mysite文件夾下的urls.py)

from django.conf.urls import url,include # include就是作分發操做的
                
    # 路由分發注意事項:應用名後面千萬不能加$
    # from app01 import urls as app01_urls
    # from app02 import urls as app02_urls
    # url(r'^app01/',include(app01_urls)),
    # url(r'^app02/',include(app02_urls))
        
    # 簡寫
    url(r'^app01/',include('app01.urls')),
    url(r'^app02/',include('app02.urls'))

名稱空間

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

#後端解析
reverse('app01:index')
reverse('app02:index')    

#前端解析
{% url 'app01:index' %}
{% url 'app02:index' %}

在給路由與視圖函數起別名的時候只須要保證永遠不出現衝突的狀況便可
一般狀況下咱們推薦起別名的時候加上當前應用的應用名前綴

url(r'^index/',views.index,name='app01_index')
url(r'^index/',views.index,name='app02_index')

虛擬環境

針對不一樣的項目,咱們有時爲了不加載資源時的消耗,只須要安裝項目所須要的功能模塊,項目用不到的一律不裝,就須要用到虛擬環境

虛擬環境就相似於一個純淨的python解釋器環境,每建立一個虛擬環境就相似於你從新下載一個python解釋器。

 

Django版本區別

路由層

1.x 用的是url
2.x、3.x 用的是path

 

 url 第一個參數是一個正則表達式

而 path 第一個參數不支持正則表達式 寫什麼就匹配什麼

若是你以爲path很差用,2.x、3.x版本給你提供了一個跟url同樣的功能
re_path 等價於1.x版本里面的url功能

#雖然path不支持正則表達式 可是它給你提供了五種默認的轉換器

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

path('login/<int:year>/',login)

#除了默認的五種轉換器以外 還支持你自定義轉換器
class MonthConverter:
regex='\d{2}' # 屬性名必須爲regex

def to_python(self, value):
    return int(value)

def to_url(self, value):
    return value # 匹配的regex是兩個數字,返回的結果也必須是兩個數字

僞靜態

url以.html結尾給人的感受好像是這個文件是寫死的,內容不會輕易的改變。這樣能夠提升你的網站被搜索引擎收藏的力度,提供網站的SEO查詢效率。

相關文章
相關標籤/搜索