Skip to content

Latest commit

 

History

History
135 lines (87 loc) · 4.13 KB

反向解析.md

File metadata and controls

135 lines (87 loc) · 4.13 KB

反向解析

在软件开发初期,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>

Django默认支持5种转换器(Path converters)

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')