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/如下圖: