9月23,Django 发布了2.0a1版本,这是一个 feature freeze 版本,如果没有什么意外的话,2.0正式版不会再增加新的功能了。按照以往的规律,预计正式版将在12月发布。

备注:Django 2.0 于12月2日已经正式发布。 (链接

2.0无疑是一个里程碑版本,移除了对 Python2.7 的支持,最少需要 3.4 以上,建议使用3.5以上的版本。

What’s new in Django2.0 文档中一共列出了三个新的特性:

  • 更简单的URL路由语法 (Simplified URL routing syntax)
  • admin应用的针对移动设备的优化改进(Mobile-friendly contrib.admin)
  • 支持SQL开窗表达式(Window expressions)

第一个特性,主要用于动态路由定义上。在Django2.0代码实现中,主要的变化是新增了 django.urls.path 函数,它允许使用一种更加简洁、可读的路由语法。比如之前的版本的代码:

url(r'^articles/(?P[0-9]{4})/$', views.year_archive),

在新版本中也可以写为:

path('articles//', views.year_archive),

新语法支持类型转化,在上述的例子中, year_archive 函数接收到的year参数就变成整数而不是字符串。

如果你有接触过 Flask 框架,就会发现和 Variable-Rules 的语法形式和功能都是相类似的。

1.问题引入

下面是 Django1.X 的一段代码:

from django.conf.urls import url

def year_archive(request, year):
year = int(year) # convert str to int
# Get articles from database def detail_view(request, article_id):
pass def edit_view(request, article_id):
pass def delete_view(request, article_id):
pass urlpatterns = [
url('articles/(?P<year>[0-9]{4})/', year_archive),
url('article/(?P<article_id>[a-zA-Z0-9]+)/detail/', detail_view),
url('articles/(?P<article_id>[a-zA-Z0-9]+)/edit/', edit_view),
url('articles/(?P<article_id>[a-zA-Z0-9]+)/delete/', delete_view),
]

考虑下这样的两个问题:

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

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

在 Django2.0 中,可以使用 path 解决以上的两个问题。

2.使用示例

这是一个简单的例子:

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>/', views.article_detail),
]

基本规则:

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

以下是根据 2.0官方文档 而整理的示例分析表:

请求URL 匹配项 视图函数调用形式
/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”)

3.path转化器

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

Django默认支持以下5个转化器:

  • str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
  • int,匹配正整数,包含0。
  • slug,匹配字母、数字以及横杠、下划线组成的字符串。
  • uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
  • path,匹配任何非空字符串,包含了路径分隔符

4.自定义转化器

4.1 定义

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

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

先看看默认的 IntConverterStringConverter 是怎么实现的:

class IntConverter:
regex = '[0-9]+' def to_python(self, value):
return int(value) def to_url(self, value):
return str(value) class StringConverter:
regex = '[^/]+' def to_python(self, value):
return value def to_url(self, value):
return value

第二个例子,是自己实现的4位年份的转化器。

class FourDigitYearConverter:
regex = '[0-9]{4}' def to_python(self, value):
return int(value) def to_url(self, value):
return '%04d' % value

4.2 注册

使用register_converter 将其注册到URL配置中:

from django.urls import register_converter, path

from . import converters, views

register_converter(converters.FourDigitYearConverter, 'yyyy')

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

5.使用正则表达式

如果上述的paths和converters还是无法满足需求,也可以使用正则表达式,这时应当使用 django.urls.re_path函数。

在Python正则表达式中,命名式分组语法为 (?Ppattern) ,其中name为名称, pattern为待匹配的模式。

之前的示例代码也可以写为:

from django.urls import path, re_path

from . import views

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

这段代码和之前的代码实现了基本的功能,但是还是有一些区别:

  • 这里的代码匹配更加严格,比如year=10000在这里就无法匹配。
  • 传递给视图函数的变量都是字符串类型,这点和 url 是一致的。

无命名分组

一般来说,不建议使用这种方式,因为有可能引入歧义,甚至错误。

6.Import变动

django.urls.path 可以看成是 django.conf.urls.url 的增强形式。

为了方便,其引用路径也有所变化,请注意下 urls 包路径的变更,不再是 conf 的子包了,目前和 viewsconf 一样,被认为是 Django 的核心组件。

1.X 2.0 备注
- django.urls.path 新增,url的增强版
django.conf.urls.include django.urls.include 路径变更
django.conf.urls.url django.urls.re_path 异名同功能,url不会立即废弃

7.代码改写

将“问题引入”一节的代码使用新的path函数可以改写如下:

from django.urls import path, register_converter
from django.urls.converters import SlugConverter class FourDigitYearConverter:
regex = '[0-9]{4}' def to_python(self, value):
return int(value) def to_url(self, value):
return '%04d' % value register_converter(SlugConverter, 'article_id')
register_converter(FourDigitYearConverter, 'year') def year_archive(request, year):
print(type(year)) # <class 'int'>
# Get articles from database def detail_view(request, article_id):
pass def edit_view(request, article_id):
pass def delete_view(request, article_id):
pass urlpatterns = [
path('articles/<year:year>/', year_archive),
path('article/<article_id:article_id>/detail/', detail_view),
path('articles/<article_id:article_id>/edit/', edit_view),
path('articles/<article_id:article_id>/delete/', delete_view),
]

8.总结

第一,目前 路由(url)到视图(View)的流程可以概括为四个步骤:

  1. url匹配
  2. 正则捕获
  3. 变量类型转化
  4. 视图调用

Django2.0 和之前相比多了 变量类型转化 这一步骤。

第二,新的path语法可以解决一下以下几个场景:

  • 类型自动转化
  • 公用正则表达式

django2:路由path语法的更多相关文章

  1. django2笔记:路由path语法

    django2笔记:路由path语法 9月23,Django 发布了2.0a1版本,这是一个 feature freeze 版本,如果没有什么意外的话,2.0正式版不会再增加新的功能了.按照以往的规律 ...

  2. 路由跟踪语法:tracert www.love125.com

    tracert  www.love125.com 路由跟踪语法

  3. Django2.0中得url路由path得用法

    Django2.0中,url得匹配规则更新了,在django1.0中,url是用正则表达式书写得,相对来说比较繁琐一些,在django2.0中进行了升级优化,改为了path from django.u ...

  4. Django2.0 path和re_path使用

    Django2.0发布后,很多人都拥抱变化,加入了2的行列.但是和1.11相比,2.0在url的使用方面发生了很大的变化,下面介绍一下: 一.实例 先看一个例子: from django.urls i ...

  5. Django-2 路由层

    U RL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表. 2.1 简单的路由配置 from django.urls import p ...

  6. vue路由高级语法糖

    1.当 <router-link> 对应的路由匹配成功,将自动设置 class 属性值 .router-link-active. 模板中可以用{{$route.params.xxx取到路由 ...

  7. angularjs路由path方式实现原理探究

    angularjs路由 https://angular.io/guide/router 通过URL解释, 来定位客户端生成的浏览器端视图. 你可绑定路由到页面的链接上, 当用户点击链接, 可以浏览到相 ...

  8. wpf path语法

    http://www.cnblogs.com/HQFZ/p/4452548.html WPF系列 Path表示语法详解(Path之Data属性语法)

  9. 使用Path语法取得对象的值

    借鉴了http://stackoverflow.com/questions/4473928/c-sharp-dynamic-string-property-path     public class ...

随机推荐

  1. Linux 文件夹和文件大小排序

    Linux 文件夹和文件大小排序 文件夹排序 du -k | sort -rn 文件排序 ls -lS -r, –reverse 依相反次序排列 -R, –recursive 同时列出所有子目录层 - ...

  2. 爬虫(十七):Scrapy框架(四) 对接selenium爬取京东商品数据

    1. Scrapy对接Selenium Scrapy抓取页面的方式和requests库类似,都是直接模拟HTTP请求,而Scrapy也不能抓取JavaScript动态谊染的页面.在前面的博客中抓取Ja ...

  3. 五十七、SAP中关于信息框的总结

    一.事务代码SE91 二.里面有我们创建过的一个消息类Z_TIANPAN_201907_MSG 三.这个消息类中有2个内容 四.我们的代码如下 五.S001效果 六.E001和W001效果 七.I00 ...

  4. linux之 文本编辑 的基础知识点

    第一步 打开终端 创建文件命令 touch 文件名.后缀名 打开文件命令 vi 文件名.后缀名 (此时进去txt文件之后为一般模式,你无法对文件进行增删改) 之后按 i    或 a    或o  都 ...

  5. MongoDB Projection

    版权所有,未经许可,禁止转载 章节 MongoDB 入门 MongoDB 优势 MongoDB 安装 MongoDB 数据建模 MongoDB 创建数据库 MongoDB 删除数据库 MongoDB ...

  6. AD在更新PCB的时候,每次封装都会改变位置?

    转载:https://blog.csdn.net/abc87891842/article/details/52538660 3.如果是很多元件的ID不一致, 手动修改太麻烦了, 可以使用AD的 &qu ...

  7. 面试官,不要再问我“Java虚拟机类加载机制”了(转载)

    关于Java虚拟机类加载机制往往有两方面的 面试题:根据程序判断输出结果和讲讲虚拟机类加载机制的流程.其实这两类题本质上都是考察面试者对Java虚拟机类加载机制的了解. 面试题试水 现在有这样一道判断 ...

  8. 一个简单完整的promiseDemo

    想要完全理解代码,需要理解 this 和闭包的含义. Promise是什么 简单来说,Promise 主要就是为了解决异步回调的问题.用 Promise 来处理异步回调使得代码层次清晰,便于理解,且更 ...

  9. Jquery获取html标签,包含该标签本身

    $(".test").prop("outerHTML"); 原生JS DOM里有一个内置属性 outerHTML,用来获取当前节点的html代码(包含当前节点) ...

  10. 四个因素决定Essay写作段落长度

    段落是一篇Essay的基石,写好Essay应从写好段落开始.那么Essay写作中一个段落多长为好?英语和修辞学教授理查德·诺德奎斯特著文介绍了一些专家的观点.从以下的译文可以看到,段落长度虽然没有固定 ...