路由

一.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' %}
原文地址:https://www.cnblogs.com/ly0123/p/11938177.html