Django 之 URL(路由)分發機制


本質

(1):它的本質是 URL 模式以及要為該 URL 模式調用的視圖函數之間的映射表。

django-admin.py startproject 運行時,該腳本會自動為你建了一份 URLconf(URL configuration)(即 urls.py 文件)。

由於它是純Python代碼(pure Python code),可以動態創建(Dynamically Constructed).

 

(2):Django 把這個記錄到ROOT_URLCONF 中

ROOT_URLCONF
Default: Not defined

自動創建的settings.py包含一個ROOT_URLCONF配置用來指向自動產生的urls.py. 打開文件settings.py你將看到如下:

ROOT_URLCONF = 'mysite.urls'
# 相對應的文件是mysite/urls.py

一個字符串代表完整的Python導入路徑URLconf根,如’mydjangoapps.urls’,可以覆蓋根據每條請求通過設置屬性urlconf傳入的HttpRequest對象。

 

(3):當訪問 URL /hello/ 時,Django 根據 ROOT_URLCONF 的設置裝載 URLconf 。 然后按順序逐個匹配URLconf里的URLpatterns,直到找到一個匹配的。

當找到這個匹配 的URLpatterns就調用相關聯的view函數,並把 HttpRequest 對象作為第一個參數。

 

(4):視圖函數必須返回一個HttpResponse,Django轉換HttpResponse為一個適合的HTTP response, 以Web page顯示出來

patterns()函數

urlpatterns should be a Python list,in the format returned by the function patterns()

#django.conf.urls.defaults.patterns()
django.conf.urls.defaults import *  #  import patterns()
patterns(prefix, pattern_description, ...)

The first arguement to patterns() is  a string prefix(前綴)

The remaining(剩余的) arguements should be tuples :

一般我們將patterns()函數返回的值保存到 urlpatterns變量中.

Once one of the regexes matches, Django imports and calls the given view, which is a simple Python function.

視圖函數使用HttpRequest對象作為第一個參數,任何值捕獲的正則表達式作為其他參數。

def myblog(request,id,name):
    pass

url()函數

You can use the url() function, instead of a tuple, as an argument to patterns()

語法:

url(regex, view, kwargs=None, name=None, prefix='')
urlpatterns =patterns('djtest.views',
     (r'^json/$','json'),
     url(r'^geturl/$','geturls',name='get_urls'),                         
)
#如果patterns()沒有前綴的話,也可這樣:
urlpatterns += patterns('',
    url(r'^geturl2/$','geturl2',name='geturl2_test',prefix='djtest.views'),
)

include()函數

include(<module or pattern_list>)

your urlpatterns can “include” other URLconf modules!

通常用於分類處理,使項目中urls高度統一.如:

urlpatterns +=patterns('',
     (r'^blog/',include('myblog.urls')),        #myblog app 中urls
     (r'^manage/',include('manager.urls')),     #manage app 中urls

注意:

(1)include() 的正則表達式並不包含一個 $ (字符串結尾匹配符),但是包含了一個斜桿/。

(2)每當Django遇到 include() 時,它將截斷匹配的URL,並把剩余的字符串發往包含的URLconf作進一步處理。

如在 myblog.app中urls如下:

#myblog.app 中的urls
urlpatterns =patterns('myblog.views',
     (r'^index/$','index'),     #博客首頁                   

那么就討論一下include()匹配的模式吧:

(1)不含變量參數

如在url輸入框中輸入 http://127.0.0.1:8000/blog/index/ 則,它會截取include()中匹配的url,這里是”blog” 接下來找到了宿主了也就是myblog.urls,那么剩余的部分,也就是”index” 去匹配myblog.urls中的url模式。

(2)含有變量參數(如命名組)

#root urls
urlpatterns += patterns('',
   (r'^(?P<username>\w+)/blog/',include('blog.urls')),                        
)

#blog.urls
urlpatterns = patterns('blog.views',
        (r'^index/$','index'),
        (r'^other/$','other'),
)

#blog.views
def index(request):
    return HttpResponse('ok')

#參數變量處理
def other(request,username):
    return HttpResponse(username)

被捕獲的 username 變量將傳遞給被包含的 URLconf,進而傳遞給那個URLconf中的 每一個 視圖函數。

那么在瀏覽器輸入:http://127.0.0.1:8000/BeginMan/blog/other/

則輸出:BeginMan

更復雜點:

(r'^blog/(?P<username>\w+)/(?P<user_id>\d+)/',include('blog.urls'))    

#.....
def index(request,username,user_id):
    return HttpResponse('ok:%s,%s' %(username,user_id)) 

輸入:http://127.0.0.1:8000/blog/BeginMan/20/index/

輸出:ok:BeginMan,20

注意 后面不要忘了去匹配blog urls的哪個urls。如(r'^index/$’)

url高級配置

參考:Django零碎知識(10):URL常用配置方法 [轉載]

1、命名組:

無命名 正則表達式組,即,在我們想要捕獲的URL部分上加上小括號,Django 會將捕獲的文本作為位置參數傳遞給視圖函數。

命名 正則表達式組來捕獲URL,並且將其作為 關鍵字 參數傳給視圖。

命名的正則表達式組的語法是:

(?P<name>pattern)

name:組名稱

pattern:匹配的某個模式,常見有:

Symbol Matching
. 任意單個字符
\d 匹配任意數字
[A-Z] 匹配A-Z任意大寫字母
[a-z] 匹配a-z任意小寫字母
[A-Za-z] 匹配a-z任意字母不論大小寫
+ 匹配一個或多個 (如:\d+)
[^xxx]+ 匹配一個或多個不為xxx的(如[^name]+)
匹配零個或一個(如:\d?)
* 匹配零個或更多(如:\d*)
{a,b} 匹配介於a ,b之間(如:\d{1,3}一個或兩個或三個數字)

 

實例如下:

('^position/(\d{4})/(\d{2})/$','position'),             #無命名 正則表達式組
('^name/(?P<year>\d{4})/(?P<month>\d{2})/$','name'),    #命名組

則輸入地址:http://127.0.0.1:8000/position/2013/15/http://127.0.0.1:8000/name/2013/15/在相應視圖函數中進行處理

#以位置參數的形式,如果位置改變,如(request,month,year),則相應的值也會隨之改變
def position(request,year,month):
    return HttpResponse('position:%s--%s' %(year,month))
    #輸出:position:2013--10
    
#關鍵字參數,key-value映射關系,與位置無關,所以當位置改變,值不變
def name(request,month,year):
    return HttpResponse('name:%s--%s' %(year,month)) 

2、傳遞額外的參數到視圖函數中

URLconf里面的每一個模式都可以包含第三個數據: 一個關鍵字參數的字典。

('^foo/$','commonView',{'name':'foo','age':22}),
('^bar/$','commonView',{'name':'bar','age':12}),
def commonView(request,name,age):
    return HttpResponse('name:%s--age:%s' %(name,age))

則輸入:http://127.0.0.1:8000/bar/http://127.0.0.1:8000/foo/ 則輸出: bar、 foo

常見應用是傳遞模板:

# urls.py

from django.conf.urls.defaults import *
from mysite import views

urlpatterns = patterns('',
    (r'^foo/$', views.foobar_view, {'template_name': 'template1.html'}),
    (r'^bar/$', views.foobar_view, {'template_name': 'template2.html'}),
)

# views.py

from django.shortcuts import render_to_response
from mysite.models import MyModel

def foobar_view(request, template_name):
    m_list = MyModel.objects.filter(is_new=True)
    return render_to_response(
template_name,
 {'m_list': m_list})

 


免責聲明!

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



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