【Django3.2学习】05-路由进阶

路由进阶

​ 在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  # 正则路由,会把url地址看成一个正则模式与客户端的请求url地址进行正则匹配

# path和re_path 使用参数一致,仅仅在url参数和接收参数时写法不一样

在这里插入图片描述

一、path路由注册

​ 从绑定路由的执行上效率,使用path比re_path的效率高很多,因为path默认情况下仅仅是通过字符串比较,而re_path是使用正则匹配

# pat("路由url", 视图函数, name="路由别名")
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<pk>[0-9]+)/$', views.profile),
]

注:

  • 首先要导入re_pathfrom django.urls import path, re_path

  • ^$分别表示正则的开始于结束

  • (?P<pk>[0-9]+)一个匹配表达式

    • ()表示一个正则表达式的匹配关系
    • ?P<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<pk>[0-9]+)/mobile/(?P<mobile>1[3-9]\d{9})/$', views.profile),
]

注:

  • 此时就表示需要两个参数,pk及mobile
  • (?P<mobile>1[3-9]\d{9})表示匹配一个手机号
    • ?P<mobile>表示匹配的对应参数是mobile
    • 1表示匹配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/<int:num>', views.demo1),
]

注:

  • 此时视图函数接收到的num就不是str类型了,而是int类型
  • <int:mobile>就是路由转换器的写法
    • int表示转换器类型是int类型
    • num对应着视图函数中的形参名称,传递到视图函数时就将值传递给num参数

4.2 注册自定义的路径转换器

对于更复杂的匹配需求,你能定义你自己的路径转换器。

转换器是一个类,包含如下内容:

  • 字符串形式的 regex 类属性。
  • to_python(self, value) 方法,用来处理匹配的字符串转换为传递到函数的类型。如果没有转换为给定的值,它应该会引发 ValueErrorValueError 说明没有匹配成功,因此除非另一个 URL 模式匹配成功,否则会向用户发送404响应。
  • 一个 to_url(self, value) 方法,它将处理 Python 类型转换为字符串以用于 URL 中。如果不能转换给定的值,它应该引发 ValueErrorValueError 被解释为无匹配项,因此 reverse() 将引发 NoReverseMatch,除非有其他 URL 模式匹配。

可以参考内置转换器的写法,内置转换器所在位置:\应用名称\Lib\site-packages\django\urls\converters.py

示例:

在user子应用下新建converters.py文件

from django.urls.converters import StringConverter, register_converter


# Custom URL Converters
# 一般会继承StringConverter,并且重写to_python方法
# to_python方法会接收一个参数,这个参数就是url中的参数,其作用是将url中的参数转换为python中的参数
# to_url方法会接收一个参数,这个参数就是python中的参数,其作用是将python中的参数转换为url中的参数
class MobileConverter(StringConverter):
    regex = r'^\+?1?\d{9,15}$'


# Register the converters
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/<mobile:mobile>', views.demo2),
]

注意:

  • 自定义路由转换器,实际上就是django在对路由进行数据转换和简写正则路由的实现,这种实现方式是基于不同的转换器类来完成,开发者要实现自定义转换器,需要编写的类必须符合官方要求的3个基本要求:

    • 必须声明属性:regex
    • 必须声明的方法:
      • to_python
      • to_url
    • 必须以类格式编写
    • 必须通过register_converter()进行注册才能被调用
  • 这种实现方式,实际就是对编程领域的设计模式的一种应用,设计模式,前任总结下来的基于固定业务场景的解决方案就是设计模式,编程中,设计模式有23种不同设计模式,其中,我们上面这种就是叫策略模式/接口模式

  • 一般在工作中,往往可以使用策略模式来进行营销活动(优惠券、打折)的实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值