django 路由
falsk路由
地址:https://www.cnblogs.com/gjjcode/articles/17398826.html
一. 版本区别
Django1.1.x 版本中的 url 和 Django 2.2.x 版本中的 re_path 用法相同。
1.1 Django1.1.x 版本
url() 方法:普通路径和正则路径均可使用,需要自己手动添加正则首位限制符号。
from django.conf.urls import url # 用 url 需要引入
urlpatterns = [
url(r'^admin/$', admin.site.urls),
url(r'^index/$', views.index), # 普通路径
url(r'^articles/([0-9]{4})/$', views.articles), # 正则路径
]
1.2 Django 2.2.x 之后的版本
path 方法:用于普通路径,不需要自己手动添加正则首位限制符号,底层已经添加。
re_path 方法:用于正则路径,需要自己手动添加正则首位限制符号。
# 用re_path 需要引入
from django.urls import re_path
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index), # 普通路径
re_path(r'^articles/([0-9]{4})/$', views.articles), # 正则路径
]
二. 路由分组
2.1 无名分组
'''url.py'''
urlpatterns = [
path('admin/', admin.site.urls),
re_path("^index/(?P[0-9]{4})/(?P[0-9]{2})/$", views.index),
]
'''views.py'''
from django.shortcuts import HttpResponse
def index(request, year, month): # 括号内正则表达式匹配到的内容, 不可调换位置, 类之于位置参数
print(year, month) # 一个形参代表路径中一个分组的内容,按顺序匹配
return HttpResponse('ok')
2.1 有名分组
'''urls.py'''
urlpatterns = [
path('admin/', admin.site.urls),
re_path("^index/(?P<year>[0-9]{4})$/(?P<mouth>[0-9]{2})/$", views.index),
]
'''views.py'''
from django.shortcuts import HttpResponse
def index(request, year, month): # 括号内正则表达式匹配到的内容。 可以调换位置, 类似于关键字参数
print(year, month) # 一个形参代表路径中一个分组的内容,按关键字对应匹配
return HttpResponse('ok')
三. 路由分发
存在问题:Django 项目里多个app目录共用一个 urls 容易造成混淆,后期维护也不方便。
解决:使用路由分发(include),让每个app目录都单独拥有自己的 urls。
'''总路由'''
from django.contrib import admin
from django.urls import path,include # 从 django.urls 引入 include
urlpatterns = [
path('admin/', admin.site.urls),
path("app01/", include("app01.urls")),
path("app02/", include("app02.urls")),
]
'''app01 中的路由'''
from django.urls import path,re_path
from app01 import views # 从自己的 app 目录引入 views
urlpatterns = [
re_path(r'^login/(?P<m>[0-9]{2})/$', views.index, ),
]
'''app02 中的路由'''
from django.urls import path,re_path
from app02 import views # 从自己的 app 目录引入views
urlpatterns = [
re_path("^xxx/(?P[0-9]{4})/$", views.xxx),
]
四. 反向解析
反向解析一般用在模板中的超链接及视图中的重定向。
4.1 普通路劲
在 urls.py 中给路由起别名,name="路由别名"。
path("login1/", views.login, name="login")
在 views.py 中,从 django.urls 中引入 reverse,利用 reverse("路由别名") 反向解析
return redirect(reverse("login"))
在模板 templates 中的 HTML 文件中,利用 {% url "路由别名" %} 反向解析。
<form action="{% url 'login' %}" method="post">
4.2 正则路径(无名分组)
在 urls.py 中给路由起别名,name="路由别名"。
re_path(r"^login/([0-9]{2})/$", views.login, name="login")
在 views.py 中,从 django.urls 中引入 reverse,利用 reverse("路由别名",args=(符合正则匹配的参数,))
return redirect(reverse("login",args=(10,)))
在模板 templates 中的 HTML 文件中,利用 {% url "路由别名" 符合正则匹配的参数 %} 反向解析。
<form action="{% url 'login' 10 %}" method="post">
4.3 正则路径(有名分组)
在 urls.py 中给路由起别名,name="路由别名"。
re_path(r"^login/(?P<year>[0-9]{4})/$", views.login, name="login")
在 views.py 中,从 django.urls 中引入 reverse,利用 reverse("路由别名",kwargs={"分组名":符合正则匹配的参数})
return redirect(reverse("login",kwargs={"year":3333}))
在模板 templates 中的 HTML 文件中,利用 {% url "路由别名" 分组名=符合正则匹配的参数 %} 反向解析。
<form action="{% url 'login' year=3333 %}" method="post">
五. 命名空间
存在问题:路由别名 name 没有作用域,Django 在反向解析 URL 时,会在项目全局顺序搜索,当查找到第一个路由别名 name 指定 URL 时,立即返回。当在不同的 app 目录下的urls 中定义相同的路由别名 name 时,可能会导致 URL 反向解析错误。
5.1
定义命名空间(include 里面是一个元组)格式如下:
include(("app名称:urls","app名称"))
'''实例:'''
path("app01/", include(("app01.urls","app01")))
path("app02/", include(("app02.urls","app02")))
在 app01/urls.py 中起相同的路由别名。
path("login/", views.login, name="login")
在 views.py 中使用名称空间,语法格式如下:
reverse("app名称:路由别名")
'''实例:'''
return redirect(reverse("app01:login")
在 templates 模板的 HTML 文件中使用名称空间,语法格式如下:
{% url "app名称:路由别名" %}
'''实例:'''
<form action="{% url 'app01:login' %}" method="post">