Django(路由)


一.URL模式

Django在檢查URL模式之前,會移除每一個申請的URL開頭的斜杠(/),因此我們在form表單中如果要訪問127.0.0.1:8000/index/地址,直接寫/index/即可。
URL模式要求尾部要有一個斜杠,因此在urls.py中要在url后添加一個/

#注意:在瀏覽器輸入127.0.0.1:8000/login發送給Django后端,django會回一個重定向/login/,然后瀏覽器重新請求這個網址。我們在瀏覽器可以看到是兩個請求
settings.py中配置APPEND_SLASH=True,瀏覽器輸入../login會重定向加上/,如果APPEND_SLASH=False,瀏覽器輸入什么就是什么,不會補全
# redirect重定向
// 表示在http:之后添加
/  表示在當前ip和端口之后添加
不加斜杠表示在當前路徑之后添加

二.正則路由

Django1.11中的路由使用url('xx',views.xx),Django2.0版本之后使用path、re_path(),Django版本1中的url相當於版本2中的re_path

1.分組

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

urlpatterns = [
    #url(r'^admin/', admin.site.urls),
    url(r"^home/([0-9]{4})/([0-9]{2})",views.home),
]
#url中的括號()相當於分組,以上分2組,括號中的內容都作為參數傳遞給views.py中的home函數
urls.py(瀏覽器輸入127.0.0.1:8000/home/2019/10)
from django.shortcuts import render,HttpResponse,reverse,redirect

#home函數使用year、month接受分組完成的2個參數
def home(req,year,month):
    return render(req,"home.html",{"year":year,"month":month})
views.py(得到參數year為2019,month為10)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
歡迎進入{{ year }}年{{ month }}日
</body>
</html>
home.html

2.命名分組

from django.conf.urls import url,include
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r"^home/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})",views.home),
]

#在django的url中,括號為分組,(?P<year>[0-9]{4})是為其添加一個組名,那么views.py中的home函數接受時的參數必須為"year"和"month"
urls.py

三.路由分發(include)

在一個項目中,會有很多的app,這就用到路由分發

新建app(python manage.py startapp app02)

如上圖:有兩個app(app01和app02),我們在瀏覽器輸入網址后,會按照django的默認配置先找到djangotest中的urls.py,因此,我們在djangotest中的urls.py中添加路由分發:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r"^app01/",include('app01.urls')), #瀏覽器輸入127.0.0.1:8000/app01/xx,會從app01中的urls.py找到xx
    url(r"^app02/",include('app02.urls')),
]
djangotest中的urls.py
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^test/,views.test'),
]

#瀏覽器輸入127.0.0.1:8000/app01/test,會找到當前py文件中的url(r'^test/,views.test')
app01中的urls.py
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r"^test/",views.test),
]

#瀏覽器輸入127.0.0.1:8000/app02/test,會找到當前py文件的test
app02中的urls.py

四.命名URL和反向解析

命名URL簡單來說就是起個別名。舉個簡單例子:

url(r'^home', views.home, name='home'),  # 給我的url匹配模式起名為 home
url(r'^index/(\d*)', views.index, name='index'),  # 給我的url匹配模式起名為index,未命名分組
url(r'^index/(?P<a>\d{4})/(?P<b>\d{2})/',views.index,name="indextest") #給url匹配模式起名為indextest,命名分組為a、b

 

反向解析:通過name="home"找到其對應的url

兩種方法:
1.通過模板找
2.通過引入reverse找

1.模板中的寫法:

{% url 'home' %} #這樣會找到name='home'的相對應的url
{% url 'index' '10'%} #找到name='index'的url為'^index/(\d*)',然后將'10'傳遞給(\d*)
{% url 'indextest' a='2019' b='10' %} #找到name='indextest'的url為'^index/(?P<a>\d{4})/(?P<b>\d{2})/',將2019和10傳給url中的參數,模板中的鍵和url匹配模式中的分組名必須一致

2.views函數中引用:

from django.urls import reverse
def redirect_to_year(request):
    return redirect(reverse("home")
    #return redirect(reverse("index",args=('10',)))  #找到name='index'的url為'^index/(\d*)',然后將'10'作為參數傳遞給(\d*)
    #return redirect(reverse("indextest",kwargs={"a":1995,"b":10})) #必須是a和b

五.命名空間

如果我們在多個不同的app中有相同的URL命名,那么反解析可能會找不到。

錯誤示例:

from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^app01/', include('app01.urls')),
    url(r'^app02/', include('app02.urls')),
    
]

#1.app01中的
from django.conf.urls import url
urlpatterns = [
    url(r'^xx/', views.xx,name="home"),
]
#1.app02中的
from django.conf.urls import url
urlpatterns = [
    url(r'^xx', views.xx,name="home"),
]

#如此,我們無論通過模板反解析還是通過reverse反解析,找到的可能是app01中的url,也可能是app02中的url
錯誤示例

解決方法:命名空間namespace

from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^app01/', include('app01.urls',namespace='app01')),#app01/home/
    url(r'^app02/', include('app02.urls',namespace='app02')),
    
]
urls.py
#1.app01中的
from django.conf.urls import url
urlpatterns = [
    url(r'^xx/', views.xx,name="home"),
]
#1.app02中的
from django.conf.urls import url
urlpatterns = [
    url(r'^xx', views.xx,name="home"),
]
app01、app02中的urls.py

使用:

 

#先從項目中的urls.py中找到namespace為app01的,再從app01中的urls.py找到name=home的
后端:reverse('命名空間名稱:別名') -- reverse('app01:home')  
hmtl:{% url '命名空間名稱:別名' %}  -- {% url 'app01:home' %}

 


免責聲明!

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



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