路由进阶
在django中所有的路由最终都会保存在一个叫 urlpatterns
中,urlpatterns必须声明在主应用下的url.py总路由中,这是由配置文件settings中的 ROOT_URLCONF = '主应用名称.urls'
配置的。
这里的配置当然可以进行修改,但是必须确保修改后的路径文件内存在 urlpatterns
变量,而且必须是列表类型。
在django运行中,当客户端发送了一个http请求到服务端,服务端的web服务器则会从http协议中提取url地址,从程序内部找到项目中添加到urlpatterns里面的所有路由信息的url进行遍历匹配。如果相等或者匹配成功,则调用当前url对应的视图方法。
在给urlpatterns路由列表添加路由的过程中,django一共提供了两个函数给开发者注册路由
from django.urls import path
from django.urls import re_path
一、path路由注册
从绑定路由的执行上效率,使用path比re_path的效率高很多,因为path默认情况下仅仅是通过字符串比较,而re_path是使用正则匹配
path("index.html4", view.index4, name="index4")
二、re_path路由注册
视图函数
def profile(request, pk):
print(pk)
return HttpResponse('获取用户信息')
路由映射关系
from django.urls import path, re_path
urlpatterns = [
re_path('^profile/(?P[0-9]+)/$', views.profile),
]
注:
- 首先要导入re_path
from django.urls import path, re_path
^
与$
分别表示正则的开始于结束(?P<pk>[0-9]+)</pk>
一个匹配表达式()
表示一个正则表达式的匹配关系?P<pk></pk>
表示后面的匹配规则对应的参数是pk参数[0-9]
表示匹配0-9之间的数字+
表示可匹配多个
改造视图函数:
def profile(request, pk, mobile):
print(pk)
print(mobile)
return HttpResponse('获取用户信息')
改造urls
from django.urls import path, re_path
urlpatterns = [
re_path('^profile/(?P[0-9]+)/mobile/(?P1[3-9]\d{9})/$', views.profile),
]
注:
- 此时就表示需要两个参数,pk及mobile
(?P<mobile>1[3-9]\d{9})</mobile>
表示匹配一个手机号?P<mobile></mobile>
表示匹配的对应参数是mobile1
表示匹配1[3-9]
表示匹配3-9之间的任意数字一次\d{9}
表示匹配任意数字九次- 请求示例:
host:port/profile/513/mobile/13112312311
- 那么请求到达视图函数后pk接收到了513,mobile接收到了13112312311
- 需要注意的是,参数到达视图函数后,参数接收到的类型都是str类型
TODO:更多正则相关可自行了解,也可对re模块进行自我学习
三、Django的url路由加斜杠的问题
在django路由中编写url地址时,为了快速查找,简易最好不在路由的后面加上
/
,当用户访问对应视图的路由时,加不加斜杠,Django都能转换到正确的url地址,这个方式虽然好,但是会导致我们客户端的静态文件的url路径如果是相对路径,则会被Django这个做法导致出现路径正确的情况,所以不要加斜杠。当然,如果我们编写的是属于前后端分离的项目的话,加不加斜杠不存在影响。
四、路由转换器
路由转换器也叫路由验证器,有两个作用:
- 把路由参数进行类型转换
- 验证路由匹配
4.1 内置转换器
下面的路径转换器在默认情况下是有效的:
str
– 匹配除了'/'
之外的非空字符串。如果表达式内不包含转换器,则会默认匹配字符串。int
– 匹配 0 或任何正整数。返回一个int
。slug
– 匹配任意由 ASCII 字母或数字以及连字符和下划线组成的短标签。比如,building-your-1st-django-site
。uuid
– 匹配一个格式化的 UUID 。为了防止多个 URL 映射到同一个页面,必须包含破折号并且字符都为小写。比如,075194d3-6885-417e-a8a8-6c931e272f00
。返回一个UUID
实例。path
– 匹配非空字段,包括路径分隔符'/'
。它允许你匹配完整的 URL 路径而不是像str
那样匹配 URL 的一部分。
示例:
视图函数:
def demo1(request, num):
print(num, type(num))
return HttpResponse('ok')
urls:
urlpatterns = [
path('demo1/', views.demo1),
]
注:
- 此时视图函数接收到的num就不是str类型了,而是int类型
<int:mobile></int:mobile>
就是路由转换器的写法int
表示转换器类型是int类型num
对应着视图函数中的形参名称,传递到视图函数时就将值传递给num参数
4.2 注册自定义的路径转换器
对于更复杂的匹配需求,你能定义你自己的路径转换器。
转换器是一个类,包含如下内容:
- 字符串形式的
regex
类属性。 to_python(self, value)
方法,用来处理匹配的字符串转换为传递到函数的类型。如果没有转换为给定的值,它应该会引发ValueError
。ValueError
说明没有匹配成功,因此除非另一个 URL 模式匹配成功,否则会向用户发送404响应。- 一个
to_url(self, value)
方法,它将处理 Python 类型转换为字符串以用于 URL 中。如果不能转换给定的值,它应该引发ValueError
。ValueError
被解释为无匹配项,因此reverse()
将引发NoReverseMatch
,除非有其他 URL 模式匹配。
可以参考内置转换器的写法,内置转换器所在位置: \应用名称\Lib\site-packages\django\urls\converters.py
示例:
在user子应用下新建 converters.py
文件
from django.urls.converters import StringConverter, register_converter
class MobileConverter(StringConverter):
regex = r'^\+?1?\d{9,15}$'
register_converter(MobileConverter, 'mobile')
视图函数
def demo2(request, mobile):
print(mobile)
return HttpResponse('ok')
urls
from django.urls import path
from user import views
from user.converters import MobileConverter
urlpatterns = [
path('demo2/', views.demo2),
]
注意:
- 自定义路由转换器,实际上就是django在对路由进行数据转换和简写正则路由的实现,这种实现方式是基于不同的转换器类来完成,开发者要实现自定义转换器,需要编写的类必须符合官方要求的3个基本要求:
- 必须声明属性:regex
- 必须声明的方法:
- to_python
- to_url
- 必须以类格式编写
- 必须通过register_converter()进行注册才能被调用
- 这种实现方式,实际就是对编程领域的设计模式的一种应用,设计模式,前任总结下来的基于固定业务场景的解决方案就是设计模式,编程中,设计模式有23种不同设计模式,其中,我们上面这种就是叫策略模式/接口模式
- 一般在工作中,往往可以使用策略模式来进行营销活动(优惠券、打折)的实现
Original: https://blog.csdn.net/qq_41224289/article/details/124086161
Author: Abo_
Title: 【Django3.2学习】05-路由进阶
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/733340/
转载文章受原作者版权保护。转载请注明原作者出处!