1. 程式人生 > >Django之(URL)路由系統

Django之(URL)路由系統

ces strong end 其中 意思 string 查找 hid example

路由系統

簡而言之,django的路由系統作用就是使views裏面處理數據的函數與請求的url建立映射關系。使請求到來之後,根據urls.py裏的關系條目,去查找到與請求對應的處理方法,從而返回給客戶端http頁面數據
技術分享

django 項目中的url規則定義放在project 的urls.py目錄下,
默認如下:

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
]

url()函數可以傳遞4個參數,其中2個是必須的:regex和view,以及2個可選的參數:kwargs和name。下面是具體的解釋:

  • regex:
    regex是正則表達式的通用縮寫,它是一種匹配字符串或url地址的語法。Django拿著用戶請求的url地址,在urls.py文件中對urlpatterns列表中的每一項條目從頭開始進行逐一對比,一旦遇到匹配項,立即執行該條目映射的視圖函數或二級路由,其後的條目將不再繼續匹配。因此,url路由的編寫順序至關重要!

需要註意的是,regex不會去匹配GET或POST參數或域名,例如對於https://www.example.com/myapp/,regex只嘗試匹配myapp/。對於https://www.example.com/myapp/?page=3,regex也只嘗試匹配myapp/。

如果你想深入研究正則表達式,可以讀一些相關的書籍或專論,但是在Django的實踐中,你不需要多高深的正則表達式知識。

性能註釋:正則表達式會進行預先編譯當URLconf模塊加載的時候,因此它的匹配搜索速度非常快,你通常感覺不到。

  • view:
    當正則表達式匹配到某個條目時,自動將封裝的HttpRequest對象作為第一個參數,正則表達式“捕獲”到的值作為第二個參數,傳遞給該條目指定的視圖。如果是簡單捕獲,那麽捕獲值將作為一個位置參數進行傳遞,如果是命名捕獲,那麽將作為關鍵字參數進行傳遞。

  • kwargs:
    任意數量的關鍵字參數可以作為一個字典傳遞給目標視圖。

  • name:
    對你的URL進行命名,可以讓你能夠在Django的任意處,尤其是模板內顯式地引用它。相當於給URL取了個全局變量名,你只需要修改這個全局變量的值,在整個Django中引用它的地方也將同樣獲得改變。這是極為古老、樸素和有用的設計思想,而且這種思想無處不在。

1.最基礎映射

用戶訪問http://127.0.0.1:8000/index 然後後端使用index()函數處理

urls.py

from django.conf.urls import include, url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^index/$‘, views.index),
  ]

1、先從創建的app下的views.py面定義處理數據的函數

2、在urls.py裏導入views

3、在urlpatterns裏寫入一條url與處理函數的l映射關系

4、url映射一般是一條正則表達式,“^” 字符串的開始,“$“ 字符串的結束

5、當寫成\^$不輸入任何url時不會在返回黃頁,而是返回後面函數裏對應的頁面。一般這一條會寫在url的最後。如

2.按照順序放置的動態路由

可以使用正則來匹配URL,將一組url使用一條映射搞定

urlpatterns = [
     url(r‘^host/(\d+)$‘, views.host),
     url(r‘^host_list/(\d+)/(\d+)$‘, views.host_list), 
]

\^host/(\d+)$
相對應的url是: ”http://127.0.0.1/host/2“ (\d+)是匹配任意的數字,在分頁時靈活運用。
在views.host中需要指定一個形式參數來接受(\d+)\$ 的值

 def user_list(request,id):
     return HttpResponse(id)

\^host_list/(\d+)/(\d+)$

相對應的url是: ”http://127.0.0.1/host/8/9“,匹配到的數字會以參數的形式按照順序傳遞給views裏面相對應的函數
在views.host_list中需要指定兩個形式參數,註意:此參數的順序嚴格按照url中匹配的順序

 def user_list(request,hid,hid2): 
     return HttpResponse(hid+hid2)

3.傳參形勢的路由

利用正則表達式的分組方法,將url以參數的形式傳遞到函數,可以不按順序排列

urlpatterns = [ 
     url(r‘^user_list/(?P<v1>\d+)/(?P<v2>\d+)$‘,views.user_list), 
 ]


(?P<v1>\d+)

正則表達式的分組,相當於一個字典, key=v1, value=\d+。 {"v1":"\d+"}

然後將此參數傳遞到views裏對應的函數,可以不按照順序

def user_list(request,v2,v1):
 
     return HttpResponse(v1+v2)
參數v1 = (?P<v1>\d+)

參數v2 = (?P<v2>\d+)

4.根據不同的app來分發不同的url

如果一個項目下有很多的app,那麽在urls.py裏面就要寫巨多的urls映射關系。這樣看起來很不靈活,而且雜亂無章。
我們可以根據不同的app來分類不同的url請求。
首先,在urls.py裏寫入urls映射條目。註意要導入include方法

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [

    url(r‘^app01/‘, include(‘app01.urls‘)),
    url(r‘^app02/‘, include(‘app02.urls‘)),

]

這條關系的意思是將url為”app01/“的請求都交給app01下的urls去處理

其次,在app01下創建一個urls.py文件,用來處理請求的url,使之與views建立映射

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

urlpatterns = [

    url(r‘index/$‘, views.index),

]

想對於url請求為: "http://127.0.0.1/app01/index/"

5.通過反射機制,為django開發一套動態的路由系統

在urls.py裏定義分類正則表達式

from django.conf.urls import patterns, include, url
from django.contrib import admin
from DynamicRouter.activator import process

urlpatterns = patterns(‘‘,
    # Examples:
    # url(r‘^$‘, ‘DynamicRouter.views.home‘, name=‘home‘),
    # url(r‘^blog/‘, include(‘blog.urls‘)),

    url(r‘^admin/‘, include(admin.site.urls)),
    
    
    (‘^(?P<app>(\w+))/(?P<function>(\w+))/(?P<page>(\d+))/(?P<id>(\d+))/$‘,process),
    (‘^(?P<app>(\w+))/(?P<function>(\w+))/(?P<id>(\d+))/$‘,process),
    (‘^(?P<app>(\w+))/(?P<function>(\w+))/$‘,process),
    (‘^(?P<app>(\w+))/$‘,process,{‘function‘:‘index‘}),
)

在同目錄下創建activater.py

#!/usr/bin/env python
#coding:utf-8

from django.shortcuts import render_to_response,HttpResponse,redirect


def process(request,**kwargs):
    ‘‘‘接收所有匹配url的請求,根據請求url中的參數,通過反射動態指定view中的方法‘‘‘
    
    app =  kwargs.get(‘app‘,None)
    function = kwargs.get(‘function‘,None)
    
    try:
        appObj = __import__("%s.views" %app)
        viewObj = getattr(appObj, ‘views‘)
        funcObj = getattr(viewObj, function)
        
        #執行view.py中的函數,並獲取其返回值
        result = funcObj(request,kwargs)
        
    except (ImportError,AttributeError),e:
        #導入失敗時,自定義404錯誤
        return HttpResponse(‘404 Not Found‘)
    except Exception,e:
        #代碼執行異常時,自動跳轉到指定頁面
        return redirect(‘/app01/index/‘)
    
    return result

6.FBV和CBV

所謂FBV和CBV 是指url 和view的對應關系

  • FBV function base view /url/ --> 函數
  • CBV class base view /url/ -->類

上述都是FBV的方式。下面對CBV進行說明:

  • urls.py
url(r‘^cbv‘,views.CBVtest.as_view()),
  • views.py
class CBVtest(View):
    def dispatch(self, request, *args, **kwargs):
        print("類似裝飾器:before")
        result = super(CBVtest, self).dispatch(request, *args, **kwargs)
        print("類似裝飾器:after")
        return result

    def get(self, request):  # 定義get方法,get請求執行這個方法
        print(request.method)
        return HttpResponse(‘cbvget‘)

    def post(self, request):  # 定義post方法,post請求執行這個方法
        print(request.method)
        return HttpResponse(‘cbvpost‘)

Django之(URL)路由系統