Django 路由
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行
路由匹配
自动补全斜杆设置
APPEND_SLASH = True
Django 1.x
url()
url(r'^test/$',views.test)
# 1.第一个参数是一个正则表达式
# 2.一旦第一个参数匹配到了内容直接结束匹配并执行对应的视图函
Django 2.x及以上
path()
url('test/',views.test)
# 1.第一个参数不支持正则表达式,写什么就匹配什么
# 2.一旦第一个参数匹配到了内容直接结束匹配并执行对应的视图函
re_path()
from django.urls import path,re_path
re_path
# 等价于 1.X里面的url方法
path转换器
转换器是Django2以后开始提供的一种url取值方式
在url里使用尖括号“<>”来捕获值,尖括号捕获值的格式<converter:name>。
其中converter为路径转换器,name为参数名,如<int:year>。
五种常用转换器
str # 匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
int # 匹配正整数,包含0。
slug # 匹配字母、数字以及横杠、下划线组成的字符串。
uuid # 匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path # 匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
自定义转换器
class MonthConverter:
regex='\d{2}' # 属性名必须为regex
def to_python(self, value):
return int(value)
def to_url(self, value):
return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
from django.urls import path,register_converter
from app01.path_converts import MonthConverter
register_converter(MonthConverter,'mon')
from app01 import views
urlpatterns = [
path('articles/<int:year>/<mon:month>/<slug:other>/',
views.article_detail, name='aaa'),
]
无名分组与有名分组
无名分组
将括号内正则表达式匹配到的内容当做位置参数传递给后面的视图函数
url(r'^test/(\d+)/$',views.test)
# 正则表达式分组:给正则表达式前后加一个小括号
有名分组
将括号内正则表达式匹配到的内容当做关键字参数传递给后面的视图函数
url(r'^testadd/(?P<id>\d+)/$',views.testadd)
# 在无名分组的情况下加上 ?P<参数名>
'''
注意!!!
1.无名有名分组不能混合使用
2.可以单个重复使用
'''
反向解析
当路由频繁变化的时候,可以使用反向解析来动态解析HTML界面上的链接地址
# 1.给路由与视图函数对应关系添加一个别名(名字自己指定 只要不冲突即可)
url(r'^index/',views.index,name='index_name')
# 2.根据该别名动态解析出一个结果,该结果可以直接访问到对应的路由
# 前端
<a href="{% url 'index_name' %}">111</a>
# 后端
from django.shortcuts import reverse
reverse('index_name')
# ps:redirect括号内也可以直接写别名
# 无名有名的反向解析
url(r'^index/(\d+)/',views.index,name='index_name')
# 后端
reverse('index_name',args=(1,)) # 只要给个数字即可
# 前端
<a href="{% url 'index_name' 1 %}"></a> # 只要给个数字即可
url(r'^index/(?P<id>\d+)/',views.index,name='index_name')
# 后端
reverse('index_name',kwargs={'id':123}) # 只要给个数字即可
# 前端
<a href="{% url 'index_name' id=666 %}"></a> # 只要给个数字即可
总结
无名有名都可以使用一种(无名)反向解析的形式
路由分发
"""
django是专注于开发应用的,当一个django项目特别庞大的时候,
所有的路由与视图函数映射关系全部写在总的urls.py很明显太冗余不便于管理
其实django中的每一个应用都可以有自己的urls.py、static文件夹、templates文件夹。
基于上述特点,使用django做分组开发非常的简便。每个人只需要写自己的应用即可,
最后由组长统一汇总到一个空的django项目中然后使用路由分发将多个应用关联到一起
"""
from django.urls import include
复杂版本
from app01 import urls as app01_urls
url(r'^app01/',include(app01_urls))
进阶版本
url(r'^app01/',include('app01.urls'))
'''总路由最后千万不能加$'''
名称空间
"""
当多个应用在反向解析的时候如果出现了别名冲突的情况,那么无法自动识别
"""
解决方式1>>>:名称空间
总路由
url(r'^app01/',include('app01.urls',namespace='app01'))
url(r'^app02/',include('app02.urls',namespace='app02'))
reverse('app01:index_name')
reverse('app02:index_name')
<a href="{% url 'app01:index_name' %}">app01</a>
<a href="{% url 'app02:index_name' %}">app02</a>
解决方式2>>>:别名不能冲突(加上自己应用名作为前缀)
url(r'^index/',views.index,name='app01_index_name')
url(r'^index/',views.index,name='app02_index_name')