如何在django2中实现路由path语法

发布时间:2021-06-04 17:48:23 作者:Leah
来源:亿速云 阅读:140

今天就跟大家聊聊有关如何在django2中实现路由path语法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

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

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

在新版本中也可以写为:

path('articles/<int:year>/', views.year_archive),

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

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

一 问题引入

下面是 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 解决以上的两个问题。

二 使用示例

这是一个简单的例子:

 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),
]

基本规则:

以下是根据 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”)

三 path转化器

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

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

四 自定义转化器

4.1 定义

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

先看看默认的 IntConverter 和 StringConverter 是怎么实现的:

 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),
  ...
]

五 使用正则表达式

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

在Python正则表达式中,命名式分组语法为 (?P<name>pattern) ,其中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),
]

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

无命名分组

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

六 Import变动

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

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

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

七 代码改写

将“问题引入”一节的代码使用新的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),
]

看完上述内容,你们对如何在django2中实现路由path语法有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。

推荐阅读:
  1. 如何在vue2中实现嵌套路由
  2. 如何在vue中实现自动化路由

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

django2

上一篇:使用Django怎么实现微信小程序的登录验证功能

下一篇:怎么在layui中使用citySelect实现省市区三级联动选择

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》