什么是反向解析
我们如果要在后台中,使用某个url地址 是需要自己进行设置的 如
from django.shortcuts import redirect
def login(request):
...
return redirect('/login/')
# 我们需要自己去写登录成功之后进行跳转的地址,这样其实特别不方便
# 如果项目稍微大一点,我们就需要去记很多的跳转地址
为什么不一开始就给这些url起一个别名,类似于一个变量名 下次要使用这个url,就直接使用这个变量名即可
path('login/', views.login, name='login'),
# 在urls中,进行路由分发的时候,多加一个name参数
# 那么我们就可以在后端,或者是前端进行使用这个路径了
我们先来看在后端中,怎么接收到这个login地址的
from django.urls import reverse
from django.shortcuts import redirect
def login(request):
print(reverse('login'))
# 根据别名反向解析出url
login_path = reverse('login')
return redirect(login_path)
在前端中,我也想使用这个路径,就需要这么写了
<form action="{% url 'login' %}" method="post">
...
</form>
名称空间
如果我有多个app
可不可能存在两个一样的别名?
这是完全可能的!!
例如qq的登录,微信的登录
我都要用login这个别名,那么怎么区分出这个别名对应那个app呢?
我们在include进行路由分发的时候,为这个app起一个namespace, 可以理解为,为app起一个别名
re_path('^app01/', include(('app01.urls', 'app01'))), # /app01/index/
re_path('^app02/', include(('app02.urls', 'app02'))), # /app02/index
# 这里的写法一定不要写错了,是include里面有一个元组,元组里面依此填内容
# 第一个参数是app下面urls的地址,第二个参数就是app的别名(namespace)
后端如何取值?
def login(request):
...
print(reverse('app01:login'))
# 有include的反向解析,需要加上别名,
# 格式:namespace:name
return ...
前端取值,和后端一样
<form action="{% url 'app01:login' %}" method="post">
...
</form>
如果在反向解析的时候,遇到的是含正则表达式的有分组匹配的
需要为你的reverse多传一个参数
# 无名分组用 args
print(reverse('login', args=(12,)))
# 你可以将匹配的内容放到这里
# 有名分组用 kwargs
print(reverse('login', kwargs={'y': 112}))
在前端中,也是这样进行操作
不过不用区分无名分组与有名分组
<form action="{% url 'login' 12 %}" method="post">
...
</form>
path方法
之前我们讲到re_path的时候,在里面可以写正则表达式,进行匹配路径,特别的方便
其实在我们的path中,也可以进行这样的操作
path('login/<int:y>/', views.login, name='login'),
这里的<int:y>就是一种通用匹配方式
int | 匹配数字 |
str | 匹配除了路径分隔符之外的其他非空字符 |
slug | 匹配字母,数字,下划线,横杠 |
path | 匹配任何字符,包括路径分割符 |
使用path中的通用匹配,就好比re_path中的有名分组
将匹配的内容传递给y
并且需要注意的是,int这个匹配规则,会将匹配上的数字,转换为int类型
所以我们叫这个写法为 转换器
自定义转换器
使用django自带的path方法中的匹配规则,有点不太够用,我们需要自定义转换器
新建类
在类中编写代码,to_python,to_url方法必不可少
将这个类注册在转换器中
from django.urls import path, register_converter
from app01 import views
# 自定义转换器
class MonConvert:
# 自定义规则(正则表达式)
regex = '\d\d'
def to_python(self, value):
# 这里的value就是匹配的值
# 可以在这里对匹配的值进行一个操作
return int(value)
# 反向解析
def to_url(self, value):
return value
# 注册转换器 类,转换器名称
register_converter(MonConvert, 'yyy')
urlpatterns = [
path('login/<yyy:y>/', views.login, name='login'),
]
# <转换器名称:关键字参数名称>
编写好之后,最好是将这个类放入到一个公共的地方
例如我放在app01下的converter.py中
我需要在app01下的__init__.py中注册这个模块
# init.py
from app01 import converter