Django请求生命周期+路由层
django请求生命周期
路由层
路由即请求地址与视图函数的映射关系,如果把网站比喻为一本书,那路由就好比是这本书的目录,在Django中路由默认配置在urls.py中
路由匹配
路由匹配的特点是,只要匹配上了就会立刻结束执行对应的视图函数
# 路由匹配机制
正则是test/ 内容是test 那么首次无法匹配
首次匹配不上 那么django还会让浏览器默认加斜杠再次发送请求
test 301
test/ 200
'在settings.py中添加APPEND_SLASH = False可以取消这个机制,但不推荐'
正则表达式限制
url方法的第一个参数其实是一个正则表达式,要正则表达式能够从用户输入的后缀中匹配到内容就算匹配上了!
# 解决路由前面可以随意乱写的问题
正则是test/ 内容是abcdefgtest/ 那么可以匹配出文本test/
可以在正则的最前面加上上箭头来限制
url(r'^admin/', admin.site.urls)
# 解决路由后面可以随意乱写的问题
正则是^test/ 内容是test/abc/edf/acd/ 那么可以匹配出文本test/
可以在正则的最后面加上$来限制
url(r'^admin/$', admin.site.urls)
'由于第一个参数是正则 所以当项目特别大 对应关系特别多的时候要格外的注意是否会出现路由顶替的现象'
# 小扩展:
可以定制一个主页面 用户不携带后缀可以直接访问(掌握)
url(r'^$',views.home)
也可以定义一个尾页 用户输入一个没有对应关系的直接返回(了解)
url(r'.*',views.error)
无名有名分组
路由匹配成功之后就会调用视图函数默认情况下会自动给视图函数传递一个request位置参数
test(request),在进行分组后会多传递一个参数。
无名:位置参数
有名:关键字参数
无名分组
url(r'^test/([0-9]{4})/$', views.test)
# 如果路由匹配中使用括号对正则表达式进行了分组,那么在调用视图函数的时候,会将括号内匹配到的内容当做位置参数传递给视图函数
def test(request,括号内正则表达式匹配到的内容)
有名分组
url(r'^testadd/(?P<user_id>[0-9]{4})$', views.testadd)4
# 给括号内的正则表达式起别名之后 匹配成功则会讲括号内匹配到的内容按照关键字参数传递给视图函数
def testadd(request,user_id=括号内正则表达式匹配到的内容)
两者是否可以混合使用
url(r'^test/(\d+)/(?P<user_id>[0-9]{4})/$', views.testadd) # 不可以
# 无名有名分组不能混合使用!!! 单个可以重复使用
url(r'^test/(\d+)/(\d+)/$', views.testadd) # 可以
url(r'^test/(?P<a>\d+)/(?P<b>\d+)',views.testadd) # 可以
反向解析
标签的href可以写网址的全称,也可以写后缀
href='https://www.baidu.com'
href='/login/'
# 自动补全当前服务的ip和port
href='127.0.0.1:8000/login/'
如果路由匹配表达式出现了变化,写在html页面上的地址全部失效,需要一个个的去修改。
通过反向解析可以获取到一个结果,该结果可以访问到一个路由,可以使程序解耦合,使得我们在修改路由匹配的时候不用去修改html的代码。
步骤1:给对应关系起别名
url(r'^func666/',views.func,name='func_view')
步骤2:使用反向解析获取结果
# 前端:
{% url 'func_view' %} # func666/ 结果可以访问路由
# 后端:
from django.shortcuts import reverse
reverse('func_view') # func666/ 结果可以访问路由
'''
reverse 接收 url 中的 name 作为第一个参数,我们在代码中就可以通过 reverse() 来获取对应的网址(这个网址可以用来跳转,也可以用来计算相关页面的地址),只要对应的 url 的name不改,就不用改代码中的网址。
'''
无名分组反向解析
步骤1:给对应关系起别名
url(r'^func666/(\d+)/',views.func,name='func_view')
步骤2:使用反向解析获取结果
'''
无法明确括号内正则表达式的内容 需要人为指定
(\d+) 位置参数 需要传参
'''
# 前端:
{% url 'func_view' 123 %} # func666/123/
# 后端:
from django.shortcuts import reverse
reverse('func_view',args=(666,)) # func666/666/
有名分组反向解析
步骤1:给对应关系起别名
url(r'^func666/(?P<id>\d+)/',views.func,name='func_view')
步骤2:使用反向解析获取结果
'''
无法明确括号内正则表达式的内容 需要人为指定
(?P<id>\d+) 关键字参数 需要传参
'''
# 前端:
{% url 'func_view' 123 %} # func666/123/
{% url 'func_view' id=123 %} # func666/123/
# 后端:
from django.shortcuts import reverse
reverse('func_view',args=(666,)) # func666/666/
reverse('func_view',kwargs={'id':1}) # func666/1/
无名有名反向解析中的手动传值
一般情况下这个值可以是数据的主键值、页面的页码、区域的编号等
比如博客园随笔,后缀的16260679
就是需要手动传的值
路由分发
如果一个django项目特别庞大 里面有很多应用 每个应用下有很多对应关系,那么django自带的路由层里面的代码就会非常非常的多,如何优化?
根据应用的不同拆分到不同的应用中即可。
django支持每个应用都可以有自己独立的:
路由层
、模板层
、静态文件
、视图层(默认)
、模型层(默认)
上述特性能够让django在分组开发上更加的方便、快捷
所有人都可以在应用中开发完整的项目功能
最后汇总到一个空的django项目中 然后通过路由分发整合所有人的应用
实例
1.创建多个应用 并去配置文件中注册
INSTALLED_APPS = [
'app01',
'app02'
]
2.在多个应用中编写相同的路由
urlpatterns = [
url(r'^index/',views.index111)
]
urlpatterns = [
url(r'^index/',views.index)
]
3.路由分发
总路由
from django.conf.urls import url, include
from app01 import urls as app01_urls
from app02 import urls as app02_urls
url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls))
"""总路由只负责分发 不负责视图函数对应"""
上述代码还可以简写
from django.conf.urls import url, include
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
名称空间
1.不同的应用使用了相同的别名 那么反向解析是否自动识别
index_view app01/index/
index_view app02/index/
2.验证发现默认情况下是不会自动识别应用前缀的 如何解决反向解析问题
方式1:名称空间
总路由添加名称空间
url(r'^app01/',include('app01.urls',namespace='app01')),
url(r'^app02/',include('app02.urls',namespace='app02'))
应用反向解析自动提示
reverse('app01:index_view')
reverse('app02:index_view')
{% url 'app01:index_view' %}
{% url 'app02:index_view' %}
方式2:只需要确保反向解析的别名在整个项目中不重复即可!!!
可以在别名的前面加上应用名的前缀
url(r'^index/',views.index,name='app01_index_view')
url(r'^index/',views.index,name='app02_index_view')
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统