Django笔记4---路由系统

Django的路由系统
Django的路由系统指的是路径和函数的对应关系,之前只知道在urls.py内修改urlpattern的内容,知道正则匹配的路径开头与视图的匹配关系.

Django的路由系统在Django中叫做URLconf系统,就像Django维护的一个目录,本质是URL与要为该URL调用的视图之间的映射表.来看看Django 1.11的URLconf官方文档是怎么说的吧:

针对Django里的app,想让其正常工作,也要为其设计一套URL以便浏览器访问该app不同的功能.在设计一个app的URL时,会建立一个Python模块,我们非正式的将其称作URLconf. URLconf用纯Python语言编写,提供了URL路径样式(正则表达式)与视图函数的对应关系.URLconf可长可短,还可以引用其他的映射关系,也可以动态生成.

简明的说,URLconf就是一个py文件,里边写上了URL和视图的对应关系,放在项目下边,作为URLconf配置文件.当有请求进来的时候,就会按照其中的配置发挥作用.URLconf文件的名称也可以自定义.在项目的根目录下约定俗成采用urls.py当做初始的URLconf配置文件.

URLconf配置文件

URLconf文件

from django.conf.urls import url
urlpatterns = [
url(regex, view, kwargs=None, name=None),]
在URLconf配置文件的开始部分,必须导入url.然后在文件中设置一个叫做urlpatterns的列表,其中的每一个元素,都是url的实例.
url可接受4个参数:

regex 是正则表达式
view 是视图函数(类)名
kwargs是一个字典,是可选的,包含额外传递给视图的参数
name是一个别名,稍后解释
制作了这样一个文件之后,这个文件就是当前站点的URLconf文件.

正则匹配详解
正则部分的匹配,是从域名加上表示根目录的/之后开始匹配的,对于常见的GET加参数的请求为例:

http://www.conyli.cc:8000/wp-admin/?article=1109
这行URL传到Django之后,Django用其中的wp-admin/部分与URLconf进行匹配,之前的域名,端口,第一个表示根目录的”/”以及表示参数的部分都会被忽略,只用wp-admin/部分.
在之前的项目中,一直使用类似:

url(r'^item_edit/', views.item_edit)
这样的模式.之前没有深究,现在可以看看具体的匹配了.

匹配item_edit/开头的URL,类似item_edit/new/也会匹配成功

r'^item_edit/'

精确匹配,仅能匹配"item_edit/",再有子路径无法匹配成功

r'^item_edit/$'

批量匹配一批由任意数字排序的URL,比较常用在内容管理系统内.

r'^book/[0-9]{2,4}/$'

分组,匹配类似book/333/ab/这样的URL,注意,如果采用分组,分组匹配的部分会把值传递给对应的视图函数.

r'^book/([0-9]{2,4})/([a-zA-Z]{2})/$'

分组命名匹配,与分组类似,但是给每个分组按照正则规则命名,会按照关键字传入视图函数

r'^articles/(?P[0-9]{4})/$'
上边的几种例子中,最后两种最为重要.仅分组不命名的情况下,匹配的url部分按照位置参数的方式传递给视图函数(视图函数必须采取各种方法接收:比如定义位置参数,采用默认值或者定义*args来接收参数).分组且命名的情况下,匹配成功的url部分按照关键字参数的方式传给视图函数(视图函数需要定义对应的关键字参数或者**kwargs用于接收关键字参数).

在今后编写URLconf和视图函数的时候,对于不需要传递字符串或者不需要返回给用户一个可重用的具体链接的时候,最好都尽量采用URLconf体系.
总结一下URLconf里的注意事项:

URLconf内的匹配顺序是从上到下,取第一个匹配成功的视图执行响应,后边不再匹配
如果要捕获URL的一部分,在对应的正则匹配的地方用分组元字符,还可以命名.匹配的值会传递给视图函数
正则的开头不要写”/”,这个不属于路径的一部分
最好用r字符串传格式,否则会面临正则二次转义的问题
所有正则捕获传递给视图函数的值都是字符串类型,需要注意视图函数中的类型转换.
正则表达式不检查请求类型,GET POST等都是按照同样的路径解析方式
还有一个小要点是,Django 对于末尾没有/的路径,会自动加上”/”然后在用这个URL去匹配,如果想关闭该功能,需要在settings.py中加上 APPEND_SLASH=False 即可.默认是True.用的不多.

由于分组传递参数的功能,以及视图函数是纯python代码的灵活性,可以实现各种批量URL处理的功能.比如不指定具体路径的时候默认返回第一页的内容:

urls.py中

from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^blog/$', views.page),
url(r'^blog/page(?P[0-9]+)/$', views.page),]

views.py中,可以为num指定默认值

def page(request, num="1"):
pass
这个url与函数的搭配就实现了如果直接输入/blogs/默认返回第一页,输入/blogs/9/会返回第9页的功能.

多重路径匹配
一开始的时候说过,只要符合URLconf配置标准的文件都可以用来进行路径解析.在路径解析的时候,对于某一个路径,还可以引入其他的路径解析文件继续再当前的基础上解析.这就类似一级路由转发给二级路由,让路径解析变得模块化和易于扩展.在url内部采用include方式进行导入.例子如下:

from django.conf.urls import include, url

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('blog.urls')),]

其中的blog.urls就是另外一个URLconf文件.会继续拿着以"blog/"开头的路径进行解析.

传递额外参数给视图函数
url的第一个参数正则表达式已经学习完毕.第二个参数已经知道是视图函数或者类,类用as_view()来注册.
现在看第三个参数.
第三个参数Kwargs是一个可选的字典类型的参数,如果不传,就不会给视图函数传入参数.如果传了参数,这个字典会被拆解成关键字参数传给视图函数.举个例子:

from django.conf.urls import url
from . import views

urlpatterns = [
url(r'^blog/(?P[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),]
这里正则用命名分组,url还带一个字典参数,假设如果year分组匹配到2019的话,views.year_archive函数接受到的参数有:默认的request, year=2019, foo = “bar”.这个在某些场景下有使用.

命名URL和URL反向解析
最后这一部分就是url的第四个参数即name=None.这个name实际上就是给匹配的那段url起一个别名.
先来看一个例子,用来理解什么叫做反向解析:
在模板里,经常会写各种超链接,尤其是在网站内部跳转的超链接,之前的项目经常写成这样:

录入单据
这样做的最大问题就是跳转的链接被硬编码了,一旦更改了url里的路径匹配,则所有用到该路径的模板全部需要重写路径.
这个时候就要用到name别名来通过别名来反向解析指定的url,不用硬编码.
修改urls.py里的内容改成如下:

url(r'^move_add/', views.move_add,name="io_ticket")
然后在模板内采用url tag 来写成如下:

<a href="{% url "io_ticket" %}?id={{ item.id }}" class="btn btn-primary">录入单据

上一篇:Django之路由系统


下一篇:HBuilderX代码提示失效解决方案