02 路由控制
路由控制
URL与要为该URL调用的视图函数之间的映射表
URLconf配置
基本格式
from django.urls import path, re_path
urlpatterns = [
path(普通匹配路径, views视图函数,参数,别名), # path('login/', views.login), 用于普通路径,不需要自己手动添加正则首尾限制符号,底层已经添加。不能用正则路径中的分组
re_path(正则匹配路径, views视图函数, 参数, 别名), # re_path(r'^index/(\d+)/$', views.index), 用于正则路径,需要自己手动添加正则首尾限制符号。能用正则路径中的分组
]
"""
参数:可选的要传递给视图函数的默认参数(字典形式)
别名:可选的name参数
urlpatterns中的元素按照书写顺序从上往下逐一匹配,一旦匹配成功则不再继续
"""
补充:
django在路由匹配时,当在浏览器中没有敲最后的斜杠,django会先拿没有敲斜杠的结果去匹配,如果都没有匹配上,会让浏览器在末尾加斜杠再发一次请求再匹配一次,如果还匹配不上才会报错
若想取消该机制不想做二次匹配,可以在settings配置文件中指定:
APEND_SLASH = False # 该参数默认是True
path转换器
默认转换器
path不支持正则表达式,但提供了五种默认的转换器
str:匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
int:匹配正整数,包含0
slug:匹配字母、数字以及横杠、下划线组成的字符串
uuid:匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00
path:匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
path('index/<int:id>/',views.index) # 会将id匹配到的内容自动转换成整型
# views.py
def index(request, id):
print(id, type(id))
return HttpResponse('index') # 123 <class 'int'>
自定义转换器
自定义url转换器的五步:
1、定义一个类,直接继承自object就可以
2、在类中定义一个属性regex,这个属性是用来限制url转换器规则的正则表达式。
3、实现to_python(self,value)方法,这个方法是将url中的值转换下,然后传给视图函数的。
4、实现to_url(self,value)方法,这个方法是在做url反转的时候,将传进来的参数转换后拼接成一个正确的url。
5、将定义好的转换器,使用'django.urls.converters.register_converter'方法注册到django中。
例如在查询文章分类时:url连接类型为:127.0.0.1:8000/article/python+django+pandas/
在app根目录创建converter.py文件
from django.urls import register_converter
class categoryconverter(object):
regex = r'\w+|(\w+\+\w+)+'
def to_python(self, value):
# 将url里的'python+django+pandas'转换成:['python', 'django', 'pandas']传给视图函数
result = value.split('+')
return result
def to_url(self, value):
if isinstance(value, list):
# 将视图函数里的['python', 'django', 'pandas']转换成'python+django+pandas'传给url
result = '+'.join(value)
return result
else:
raise runtimeerror('转换url的时候,分类参数必须为列表')
# register_converter(上面自己定义的类名,自定义的类型名(在urls.py文件中使用))
register_converter(categoryconverter, 'cate')
在app根目录下的__init__.py中添加:
from . import converters
在urls.py中使用即可,如:
path('article/<cate:classify>',views.article_classify_list,name='article_classify'),
分组匹配
使用正则表达式分组匹配(通过括号)来捕获URL中的值并以参数形式传递给视图。捕获的参数为字符串
无名分组
re_path(r'^test/([0-9]{4})/', views.test)
路由匹配时会将括号内正则表达式匹配到的内容当做位置参数传递给视图函数,test(request,2019)
有名分组
re_path(r'^test/(?P<year>\d+)/', views.test)
路由匹配时会将括号内正则表达式匹配到的内容当做关键字参数传递给视图函数,test(request,year=2019)
注意:
无名分组和有名分组不能混合使用,但一种分组可以使用多个
re_path(r'^test/(\d+)/(\d+)/', views.test)
re_path(r'^test/(?P<year>\d+)/(?P<month>\d+)/', views.test)
视图函数可以指定默认值:test(request,year='2022')
include路由分发
当django项目特别庞大时,路由与视图函数对应关系特别多,总路由urls.py代码太过冗长不易维护
每一个应用都可以有自己的urls.py、static文件夹、templates文件夹
正是基于上述条件可以实现多人开发,开发完成后只需要创建一个空的django项目,然后将多人开发的app全部注册进来 ,在总路由实现一个路由分发而不再做路由匹配(分发到对应的app中)
同样当应用的视图函数特别大时,可以建一个views文件夹,里面根据功能的细分再建不同的py文件
from django.conf.urls import include
# 方法1:
path('app01/', include(('app01.urls', 'app01')),
path('app02/', include(('app02.urls', 'app02')),
# 方法2:
"""
app01/urls中添加: app_name = 'app01'
app02/urls中添加: app_name = 'app02'
"""
path('app01/', include('app01.urls'),
path('app02/', include('app02.urls'),
传递额外的参数给视图函数
URLconfs 具有一个钩子,用来传递一个Python字典作为额外的参数传递给视图函数。
# 对于 /blog/2005/ 请求,Django将调用views.year_archive(request, year='2005', foo='bar')
urlpatterns = [
re_path(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]
URL反向解析
反向解析
给URL匹配规则起个名字,一个URL匹配模式起一个名字,这样就不需要写死URL,只需要通过名字来调用当前的URL。
1.先给url和视图函数对应关系起别名
path('index/',views.index,name='kkk')
2.反向解析
- 后端反向解析:后端可以在任意位置通过reverse反向解析出对应的url
from django.shortcuts import reverse
reverse('kkk') - 前端反向解析
{% url 'kkk' %}
注意:
应用间不能用同样的URL名称,可在URL名称中加上一个前缀比如应用名,称或者使用名称空间(不推荐)
无名分组反向解析
re_path(r'^index/(\d+)/$',views.index,name='kkk')
后端反向解析:reverse('kkk',args=(1,)) # 后面的数字通常都是数据的id值
前端反向解析:{% url 'kkk' 1%} # 后面的数字通常都是数据的id值
有名分组反向解析
re_path(r'^index/(?P<year>\d+)/$',views.index,name='kkk')
后端方向解析:
方式一:reverse('kkk',args=(1,)) # 推荐,减少你的脑容量消耗
方式二:reverse('kkk',kwargs={'year':1}))
前端反向解析:
方式一:<a href="{% url 'kkk' 1 %}">1</a>
方式二:<a href="{% url 'kkk' year=1 %}">1</a>
命名空间模式
多个app起了相同的别名时用反向解析,并不会自动识别应用前缀,解决方法除了别名加app名前缀,还可以使用名称空间
总urls.pyt:
path('app01/',include('app01.urls',namespace='app01'))
path('app02/',include('app02.urls',namespace='app02'))
app01的urls.py: re_path(r'^(?P<pk>\d+)/$', views.index, name='index')
app02的urls.py: re_path(r'^(?P<pk>\d+)/$', views.index, name='index')
后端解析:
reverse('app01:index',args=(1,))
reverse('app02:index',args=(1,))
前端解析:
{% url 'app01:index 1' %}
伪静态
伪静态网页的设计是为了增加百度等搜索引擎seo查询力度,所有的搜索引擎其实都是一个巨大的爬虫程序
网站优化相关,通过伪静态可以提高网站被查询出来的概率
path('index.html',views.index),
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY