1. 程式人生 > 實用技巧 >Django 中URL和Views相關知識梳理(極簡版)

Django 中URL和Views相關知識梳理(極簡版)

提示:僅供梳理參考,很多相關的細節內容忽略。

1.URL

(1)URL匹配的規則是正則,關於正則不再贅述。

(2)URL優先順序順序:從urlpatterns的底部開始搜尋,一直往上搜索,需要注意的是,並不是一搜到匹配的URL正則式就停止了,而是繼續往上搜索,如果上面還有匹配的URL正則,則上面的有效,所以在urlpatterns中寫url與views或者include的對映關係時,應該是細分的在上面,比較粗略的正則寫下面,但如果採用'^ some RegEx$' 的精確的正則,就不存在優先順序的問題。

(3)url帶參:通過正則name group實現,比如'^fruit/(?P<fruit_name>[a-zA-Z]+)/',可以獲取一個名為'fruit_name'的引數,該引數至少有一個字母,然後傳遞給相應的view函式,如:

def someMethod(request,fruit_name,extra):  #extra 解釋見下面的(4)
    
    #something using fruit_name
    return render(request,'demo.html',context_dict)

  

該函式可以是FVB或者CVB,如果是CVB可直接傳遞至相應的template模板,如url('^someRegEx$',TemplateView.as_view(template_name='drinks/index.html'))

(4)url的optional extra:例如 url('^someRegEx$',views.someMethod,{'extra':'extra_data'}),最後一項就是optional extra,可選的引數,該引數隨url中的引數一起,可以被傳入views 中的函式或者CVB指明的模板。

(5)url的name:在對映url和view函式時候,經常帶一個name,如 url('^apple/$',views.appleMethod,name='apple'),這裡name是為了反向代理,意思就是在html模板中可以使用{% url 'apple' %}來代表硬生生寫的 'apple/$'這個url,因為如果^apple/$'變動了,所有含有硬生生寫的'apple/$'都要變,非常麻煩。

(6)如果是多個app,則每個app下的name不能一樣,因為這樣就是多個url對應一個name,反向代理,一個name對應哪個url?不確定。一個粗暴的方法就是每個name都加字尾,但也非常不方便。所以為了可以讓每個app下的name 也可以相同,引入了namespace,但namespace必須與include一起使用,所以在reverse或者模板中就可以用“namespace:name"的方法來反向代理url。

(7)【用的情況比較少】如果多個url對應同一個app(必須用多個include+namespace,是使用app_name的前提),需要在該app的url中設定app_name,,這樣可以通過app_name:name(該name是該app中urlpatterns中的name)來動態的捕捉到是通過哪個url進入的該app的url。如主urls.py中有


urlpatterns = [ path('admin/', admin.site.urls), url('^coffee-banners/',include('banners.urls',namespace='coffee-banners')), url('^food-banners/',include('banners.urls',namespace='food-banners')) ]

 banners的urls.py為:

app_name='banners_adverts'
urlpatterns=[
    url('^$',views.index,name='index')
]

banners的views.py:

def index(request):
    return render(request,'banners/index.html')

banners的index.html為:

{% extends '../base.html' %}
{% block body_block %}
{% url 'banners_adverts:index' %}
{% endblock %}

 所以當通過/food-banners/進來時,{% url 'banners_adverts:index' %}顯示的是/food-banners/如下圖:

當通過/coffee-banners/進來時,{% url 'banners_adverts:index' %}顯示的是/coffee-banners/如下圖: