03-路由控制6——path方法+自定义转换器

1、django2.0版本的re_path方法跟django1.0版本的url方法的用法完全一致
2、django2.0版本新增了path方法:

在whw_dj2项目中:

全局的urls.py文件中

from django.contrib import admin        
from django.urls import path,re_path,include
urlpatterns = [
    path('admin/', admin.site.urls),
    #分发
    re_path('^app01/',include('app01.url'))
        ]

app01的url.py文件中

说明如下
#path方法——新内容:
 #考虑下这样的两个问题: 
 第一个问题,函数year_archive中year参数是字符串类型的,因此需要先转化为整数类型的变量值,当然year=int(year)不会有诸如如TypeError或者ValueError的异常。那么有没有一种方法,在url中,使得这一转化步骤可以由Django自动完成? 

 第二个问题,三个路由中article_id都是同样的正则表达式,但是你需要写三遍,当之后article_id规则改变后,需要同时修改三处代码,那么有没有一种方法,只需修改一处即可? 

 在Django2.0中,可以使用 path 解决以上的两个问题。
代码如下
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    re_path('^login$/',views.login,name='LOGIN'),
    #有名分组
    re_path('^articles/(?P<y>[0-9]{4})/(?P<m>[a-zA-Z0-9]+$)',views.get_y_m),
    ###path方法
    #这里的int是内置的转换器
    path('articles/<int:year>/<int:month>/',views.get_year_month),

    ]
基本规则如下
#基本规则:
(1)使用尖括号(<>)从url中捕获值。
(2)捕获值中可以包含一个转化器类型(converter type),比如使用 捕获一个整数变量。
(3)若果没有转化器,将匹配任何字符串,当然也包括了 / 字符。
(3)无需添加前导斜杠。

app01的views.py文件中

from django.shortcuts import render,HttpResponse
# Create your views here.
def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    elif request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'whw' and pwd == '123':
            return HttpResponse('OK!')
        else:
            return HttpResponse('ERROR!')

def get_y_m(request,m,y):
    print(y)
    print(type(y))#这里默认的是str类型
    return HttpResponse('y:%s;m:%s'%(y,m))

    
def get_year_month(request,year,month):
    print(year,minth)
    print(type(year),type(month))
    return HttpResponse(year,month)

3、转换器说明如下

3-1-path转化器

文档原文是Path converters,暂且翻译为转化器。

3-2-Django默认支持以下5个转化器

1、str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
2、int,匹配正整数,包含0。
#slug用的比较多——相当于匹配下面的字符串——省去了正则表达式
3、slug,匹配字母、数字以及横杠、下划线组成的字符串。
4、uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00)#不常用
#注意不能用?,它是GET请求数据的分隔符,左右部分的分隔符!
5、path,匹配任何非空字符串,包含了路径分隔符

3-3-注册自定义转换器

对于一些复杂或者复用的需要,可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:

1、regex 类属性,字符串类型
2、to_python(self, value) 方法,value是由类属性 regex 所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。
3、to_url(self, value) 方法,和 to_python 相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。

例子

(1)app01应用中,新建一个url_convert.py文件,这个文件新建一个类

注意这个类的名字可以随便取,但是类中的属性与方法名是固定的!

class FourDigitYearConverter:  
    #规则字符串
    regex = '[0-9]{4}'
    #to_python方法
    def to_python(self, value):  
        return int(value)
    #to_url方法——用于反向解析
    def to_url(self, value):  
        return '%04d' % value
(2)使用register_converter 将其注册到URL配置中
#在app01的url.py文件中注册:
from django.urls import register_converter, path  
#将写好的url_convert引入:
from app01 import url_convert, views
#用yyyy做替换:      
register_converter(url_convert.FourDigitYearConverter, 'yyyy')  

from django.urls import path,re_path,register_converter

from app01 import views,url_convert

register_converter(url_convert.four_year_to_int,'yyyy')

urlpatterns = [
    re_path('^login/$',views.login,name='LOGIN'),

    #有名分组+反向解析
    re_path('^articles/(?P<y>[0-9]{4})/(?P<m>[a-zA-Z]+$)',views.get_y_m),

    path('articles/<yyyy:year>/<yyyy:month>',views.get_year_month),
    ]
       
#注意浏览器中要这样写:http://127.0.0.1:8000/app01/articles/1000/1234
#year跟month都是4位,因为规则是:regex = '[0-9]{4}'
posted on 2019-05-17 20:53  江湖乄夜雨  阅读(364)  评论(0编辑  收藏  举报