在软件开发初期,url地址的路径设计可能并不完美,后期需要进行调整,如果项目中很多地方使用了该路径,一旦该路径发生变化,就意味着所有使用该路径的地方都需要进行修改,这是一个非常繁琐的操作。
解决方案就是在编写一条url(regex, view, kwargs=None, name=None)时,可以通过参数name为url地址的路径部分起一个别名,项目中就可以通过别名来获取这个路径。以后无论路径如何变化别名与路径始终保持一致。
上述方案中通过别名获取路径的过程称为反向解析
在views.py中,反向解析的使用
from django.shotcuts import reverse
url = reverse('index_page')
在模板文件中,反向解析的使用
{% url 'login_page' %}
# 1 针对无名分组,比如我们要反向解析出:/aritcle/1/ 这种路径,写法如下
在views.py中,反向解析的使用:
url = reverse('article_page',args=(1,))
在模版login.html文件中,反向解析的使用
{% url 'article_page' 1 %}
# 2 针对有名分组,比如我们要反向解析出:/user/1/ 这种路径,写法如下
在views.py中,反向解析的使用:
url = reverse('user_page',kwargs={'uid':1})
在模版login.html文件中,反向解析的使用
{% url 'user_page' uid=1 %}
针对项目中创建了多个app中出现相同的路径别名,在反向解析的时候会出现覆盖现象。
解决办法:
1、总urls.py在路由分发时,指定名称空间
url(r'^app01/', include(('app01.urls','app01'))),
2、修改每个app下的view.py中视图函数,针对不同名称空间中的别名’index_page’做反向解析
url=reverse('app02:index_page') # 解析的是名称空间app02下的别名'index_page'
注:
1、在视图函数中基于名称空间的反向解析,
用法如下 url=reverse('名称空间的名字:待解析的别名')
2、在模版里基于名称空间的反向解析,用法如下
<a href="{% url '名称空间的名字:待解析的别名'%}">哈哈</a>
str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
int,匹配正整数,包含0。
slug,匹配字母、数字以及横杠、下划线组成的字符串。
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
我们可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:
regex
类属性,字符串类型to_python(self, value)
方法,value是由类属性regex
所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。to_url(self, value)
方法,和to_python
相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。
1、在app01下新建文件path_ converters.py,文件名可以随意命名
class MonthConverter:
regex='\d{2}' # 属性名必须为regex
def to_python(self, value):
return int(value)
def to_url(self, value):
return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
2、在urls.py中,使用register_converter
将其注册到URL配置中:
from django.urls import path,register_converter
from app01.path_converts import MonthConverter
register_converter(MonthConverter,'mon')
from app01 import views
urlpatterns = [
path('articles/<int:year>/<mon:month>/<slug:other>/', views.article_detail, name='aaa'),
]
3、views.py中的视图函数article_detail
from django.shortcuts import render,HttpResponse,reverse
def article_detail(request,year,month,other):
print(year,type(year))
print(month,type(month))
print(other,type(other))
print(reverse('xxx',args=(1988,12,'hello'))) # 反向解析结果/articles/1988/12/hello/
return HttpResponse('xxxx')