Django2.0路由层-URLconf

DJango2.0路由层-URLconf

  • URL配置(URLconf)就像Django 所支撑网站的目录树。
  • 它的本质是URL与要为该URL调用的视图函数之间的映射表;
    • 对于客户端发来的某个URL调用哪一段逻辑代码对应执行。
    • 一般来说,一个路径对应一个视图函数。它并非一一对应!
    • 多个路径可以对应一个视图函数,但是一个路径,不能对应多个视图函数。

urlpatterns

urls.py中默认就有urlpatterns,可以把它看作一个存放了映射关系的列表。
django2.0中常用的是path()方法,还可以使用re_path()方法来兼容1.x版本中的url()方法。

  • 用法大致都是一样的,这些方法主要接收4个参数:
    • 2个是必須的:regextview
    • 2个是可选的:kwargsname
  • regex(正则表达式):
    • regex是正则表达式的通用缩写,可以用正则来匹配url地址。
    • 用户请求url地址,urls.py对urlpatterns列表中的每一项条目从头开始进行逐一对比,一旦遇到匹配项,立即执行该条目映射的视图函数或下级路由,其后的条目将不再继续匹配。
    • 所以,url路由的编写顺序非常重要!
    • regex不会去匹配GET或POST参数或域名。
  • view(视图函数):
    • view指的是处理当前url请求的视图函数。
    • 当正则表达式匹配到某个条目时,自动将封装的HttpRequest对象作为第一个参数,正则表达式“捕获”到的值作为第二个参数,传递给该条目指定的视图view。
    • 如果是简单捕获,那么捕获值将作为一个位置参数进行传递,如果是命名捕获,那么将作为关键字参数进行传递。
  • kwargs:
    • 任意数量的关键字参数可以作为一个字典传递给目标视图。
  • name(别名):
    • 对你的URL进行命名,让你能够在Django的任意处,尤其是模板内显式地引用它。
    • 这是一个非常强大的功能,相当于给URL取了个全局变量名,不会将url匹配地址写死。

实例

from django.contrib import admin
from django.urls import path

from . import views

urlpatterns = [
    path('articles/2018/', views.special_case_2018),
    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),
]

注:

  • 捕获一段url中的值,使用的是尖括号,而不是圆括号;
  • 可以转换捕获到的值为指定类型,比如例子中的int。
    • 默认情况下,捕获到的结果保存为字符串类型,不包含/这个特殊字符;
  • 匹配模式的开头可以不添加/,默认情况下,每个url都带一个最前面的/,共有的部分,不用特别写了。

匹配例子:

  • /articles/2017/06/ 将匹配第三条,并调用views.month_archive(request, year=2017, month=6);
  • /articles/2018/匹配第一条,并调用views.special_case_2018(request);
  • /articles/2018将一条都匹配不上,因为它最后少了一个斜杠,而列表中的所有模式中都以斜杠结尾;
  • /articles/2016/05/building-a-django-site/ 将匹配最后一个,并调用views.article_detail(request, year=2016, month=5, slug="building-a-django-site"。

path转换器

默认情况下,Django内置下面的路径转换器:

  • str:匹配任何非空字符串,但不含斜杠/,默认使用;
  • int:匹配0和正整数,返回一个int类型;
  • slug:可理解为注释、后缀、附属等概念,是url在最后的一部分解释性字符。
    • 该转换器匹配任何ASCII字符以及连接符和下划线;
  • uuid:匹配一个uuid格式的对象。为了防止冲突,规定必须使用破折号,所有字母必须小写。
    • 0863561d3-9527-633c-b9b6-8a032e1565f0。返回一个UUID对象;
  • path:匹配任何非空字符串,重点是可以包含路径分隔符/
    • 这个转换器可以帮助你匹配整个url而不是一段一段的url字符串。

自定义path转换器

写一个类,并包含下面的成员和属性:

  • 类属性regex:一个字符串形式的正则表达式属性;
  • to_python(self, value) 方法:
    • 用于将匹配到的字符串转换为你想要的那个数据类型,并传递给视图函数。
    • 如果转换失败,它必须弹出ValueError异常;
  • to_url(self, value)方法:
    • 将Python数据类型转换为一段url的方法,to_python方法的反向操作。

例如,新建一个converters.py文件,与urlconf同目录,写个下面的类:

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

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

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

写完类后,在URLconf 中注册,并使用它,如下所示,注册了一个yyyy:

from django.urls import register_converter, path

from . import converters, views

register_converter(converters.FourDigitYearConverter, 'yyyy')

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

使用正则表达式

Django2.0的url虽然改‘配置’了,但它依然向老版本兼容。
而这个兼容的办法,就是用re_path()方法代替path()方法。
re_path()方法在骨子里,根本就是以前的url()方法,只不过导入的位置变了。

下面是一个例子,对比一下Django1.11时代的语法,有什么太大的差别?

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),
]
  • 与path()方法不同的在于两点:
    • year中匹配不到10000等非四位数字,这是正则表达式决定的
    • 传递给视图的所有参数都是字符串类型。
      • 不像path()方法中可以指定转换成某种类型。在视图中接收参数时一定要小心。

参考引用:
http://www.liujiangblog.com/blog/17/

猜你喜欢

转载自www.cnblogs.com/tielemao/p/9252239.html