August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
Django 2.0 path使用方法
发布:2021年01月06日 | 作者:augustrush | 阅读量: 1096

最近想把本博客Django版本upgrade到2.X,毕竟1.11.X已经end of extended support了。之前也尝鲜过Django 2.X,对path也一知半解,今天通过文档总结一下。


概况

在Django2.0其中一个新特性为:简化Url路由的语法

在代码上主要体现在新增了django.urls.path函数,它带来了更简洁、更可读的路由语法。


# 1.11的URL
url(r'^articles/(?P<year>[0-9]{4})/$',  views.year_archive),

# 2.0的URL
path('articles/<int:year>', views.year_archive)


例如

新语法支持URL参数的类型转化。year_archive函数接收到的year参数作为参数,并且会自动转换year为整型而不是字符串。

在Django 1.X里,我们需要对year做类型转换:

def year_archive(request, year):
    year = int(year)


在新的语法里,URL字符串有以下规则:

  1. 在URL里使用尖括号<>来捕获值

  2. 尖括号捕获值的格式<converter:name>。其中converter为路径转换器,name为参数名,如。对于捕获的值没有路径转换器,那么它会匹配除了斜杠(/)外的所有字符作为捕获的值。

  3. url不需要以斜杠开头。


官网上的案例:

from django.urls import path

from . import views

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    path('articles/<int:year>/', views.year_archive),
    path('articles/<int:year>/<int:month>/', views.month_archive),
    path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]


匹配示例:

  • /articles/2005/03/:匹配到第3个规则,调用views.month_archive(request, year=2005, month=3)

  • /articles/2003/:匹配到第1个规则,调用views.special_case_2003(request)

  • /articles/2003:没有匹配到规则,原因是所有的规则都是以斜杠结尾

  • /articles/2003/03/building-a-django-site/:匹配到第4个规则,调用views.article_detail(request, year=2003, month=3, slug=”building-a-django-site”)


路径转换器

URL里捕获的值使用Path Converter来对值做转换,如类型转换。Django2.0自带了默认的Path Converter,同时也支持自定义Path Converter。


默认Path Converter

Django 2.0自带的PathConverter包括:

  • str: 匹配除了路径分隔符(/)之外的非空字符串,如果没有转换器,默认使用str作为转换器。

  • int: 匹配0及正整数。

  • slug: 匹配字母、数字以及横杠、下划线组成的字符串。

  • uuid: 匹配格式化的UUID。

  • path: 匹配任何非空字符串,包含了路径分隔符(/)。它允许你匹配完整的URL路径而不是像str那样只匹配URL的一部分。


自定义Path Converter

当默认的PathConverter不能满足需求时,Django2.0支持用户注册自定义的PathConverter。

Path Converter是一个类,定义Converter类需要包含下面的属性或方法:

  • 字符串形式的regex类属性。

  • to_python(self, value) 方法,它处理匹配的字符串转换为应该传递到函数的类型。如果没有转换为给定的值,它应该引发ValueError。ValueError被解释为不匹配,因此向用户发送404响应。

  • to_url(self, value) 方法,和to_python相反,它会将Python类型转换为在URL中使用的字符串。


官网上的示例:

class FourDigitYearConverter:
    regex = '[0-9]{4}'

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return '%04d' % value


url.py中使用register_converter()来注册自定义的转换器类:

from django.urls import path, register_converter

from . import converters, views

register_converter(converters.FourDigitYearConverter, 'yyyy')

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    path('articles/<yyyy:year>/', views.year_archive),
    ...
]


使用正则表达式

Django2.0也支持我们使用正则表达式来捕获值。

注意:用正则表达式捕获值,需要使用re_path(),而不是path()。

正则表达式建议使用命名正则表达式组,语法如下:

(?Pregex)

其中,尖括号里的name为分组名,regex为正则表达式。

re_path()其实就相当于Django1.X中的url()

from django.urls import path, re_path

from . import views

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
]

与前面的示例不同点:

  • 这里的代码匹配更加严格,比如year是10000就无法匹配,因为它超出了正则规定的4位数

  • 传给view函数的参数为字符串类型,这点和Django1.X使用url()是一样的。


设置默认值

from django.urls import path

from . import views

urlpatterns = [
    path('blog/', views.page),
    path('blog/page<int:num>/', views.page),
]

# View (in blog/views.py)
def page(request, num=1):
    # Output the appropriate page of blog entries, according to num.
    ...


在上面的例子中,两个URL模式都指向了相同的视图--views.page但是第一个样式不能在URL中捕获到任意东西。如果第一个URL模式去匹配URL,page()函数会使用它默认参数num=1。如果第二个URL模式去匹配URL,page()函数都会使用捕获到的num参数。




  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed