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

【Django3.2学习】05-路由进阶,第1张

路由进阶

​ 在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[0-9]+)/$', views.profile),
]

注:

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

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

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

    • ()表示一个正则表达式的匹配关系
    • ?P表示后面的匹配规则对应的参数是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
  • (?P1[3-9]\d{9})表示匹配一个手机号
    • ?P表示匹配的对应参数是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/', views.demo1),
]

注:

  • 此时视图函数接收到的num就不是str类型了,而是int类型
  • 就是路由转换器的写法
    • 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


# 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/', views.demo2),
]

注意:

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

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

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/580115.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存