Django 路由控制的实现代码


Posted in Python onNovember 08, 2018

一、URL路由基础

URL是web服务的路口,用户通过浏览器发送过来的任何请求都会被发送到一个指定的URL地址里,然后被响应。

在django项目中编写路由就是向外暴露我们接收哪些URL的请求,除此之外任何的URL都不会被处理,URL路由就是web服务对外暴露的API

二、Django处理请求

确定要使用的 URLconf 模块,通常是settings中 ROOT_URLCONF 设置的值,如果传入的 HttpRequest 对象具有 urlconf 属性(中间件设置),则使用其值代替settings中 ROOT_URLCONF

Django加载模块并查找可用的 urlpatterns ,它是 django.conf.urls.url() 实例的一个列表

按顺序运行每个URL模式,匹配成功就停下来,所以 顺序很关键

匹配成功导入给定的视图,它是一个python函数,或基于类的视图,视图将获得如下参数

  • 一个HttpRequest实例
  • 如果匹配的正则表达式返回了无名分组,那么它将作为位置参数提供给视图
  • 关键字参数由正则的有名分组组成,但是可以被django.conf.urls.url()的可选参数kwargs覆盖

如果没有URL模式匹配,或者过程出错了,将调用错误处理视图

三、简单的路由配置
from django.conf.urls import url

urlpatterns=[
  url(正则表达式,view视图函数,参数,别名)
]

示例的URLconf:

from django.urls import url

from . import views

urlpatterns = [
  url(r'^articles/2003/$', views.special_case_2003),
  url(r'^articles/([0-9]{4})/$', views.year_archive),
  url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
  url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

注:

  • 从URL中捕获一个值,可以加园括号或者尖括号
  • 不要添加前导的防斜杠,因为每个URL都有,例如,应该是 ^articles 而不是 ^/articles
  • 每个正则表达式前面的'r'是可选的,建议添加上,它告诉python这个字符串中的任何字符都不应该被转义

请求的例子及匹配的url

/articles/2005/03/将匹配列表中的第三个模式。Django将调用函数views.month_archive(request, '2005', '03')。
/articles/2005/3/不匹配任何URL模式,因为列表中的第三个模式要求月份是两个数字。
/articles/2003/将匹配列表中的第一个模式不是第二个,因为模式按顺序从上往下匹配,第一个会首先被匹配。Django会调用函数views.special_case_2003(request)
/articles/2003不匹配任何一个模式,因为每个模式都要求URL以一个斜杠结尾。
/articles/2003/03/03/将匹配最后一个模式。Django将调用函数views.article_detail(request, '2003', '03', '03')。

是否开启URL访问地址后面 不为/跳转至带有/路径的配置项

APPEND_SLASH=True

Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其作用就是自动在网址结尾加'/'。

四、有名分组

有名分组的语法是 (?P<name>pattern) ,其中name是组的名字,pattern是匹配的模式

使用有名分组重写上面的URLconf:

from django.conf.urls import url

from . import views

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

注:捕获的值作为关键字参数而不是位置参数传递给视图函数。

/articles/2005/03/ 请求将调用 views.month_archive(request, year='2005', month='03') 函数,而不是 views.month_archive(request, '2005', '03') 。

五、无名分组有名分组总结

1.无名分组

按位置传参

分组之后,将分组好的数据当做位置传参到视图函数,所以视图函数需要定义形参

示例:

​ url: (r'^articles/([0-9]{4})/([0-9]{2})$', views.article_detail)

​ 视图函数: def article_detail(request,*args)

2.有名分组

按关键字传参

分组后,会把分组出来的数据当做关键字参数传到视图函数,所以视图函数需要定义形参,形参名字和分组的名字相对应,与顺序无关

示例:

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

​ 视图函数: def article_detail(request,mounth,year)

注:有名分组和无名分组最好不要混用

六、反向解析

在django项目中,一个常见的需求是获得URL的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向)。不希望通过硬编码URL

Django提供了一种解决方案,只需在URL中提供一个name参数,并赋值一个你自定义的、好记的、直观的字符串。

  • 在模板中:使用url模板标签
  • 在python代码中,使用reverse()函数

示例:

url配置:

  • 无参数:url(r'^publishadd111/$',views.publishadd,name='ddd'),
  • 无名分组:url(r'^publishadd/([0-9]{4})/([0-9]{2})/$', views.publishadd,name='ddd'),
  • 有名分组:url(r'^publishadd/(?P<year>[0-9]{4})/(?P<mounth>[0-9]{2})/$',views.publishadd,name='ddd'),

模板层:

  • 无参数: {% url 'ddd' %}
  • 无名分组: {% url 'ddd' 2018 12 %} 空格隔开,传多个值
  • 有名分组: {% url 'ddd' 2018 12 %} 还可以 {% url 'ddd' year=2018 mounth=12 %}

视图层:

from django.shortcuts import reverse
  • 无参数: url=reverse('ddd')
  • 无名分组: url=reverse('ddd',args=(2018,12,))
  • 有名分组: url=reverse('ddd',args=(2018,12,)) 还可以 url=reverse('ddd',kwargs={'year':2018,'mounth':12})

七、路由分发

在每个app里各自创建一个urls.py路由模块,然后从根路由出发,将app所属的url请求全部转发到相应的urls.py模块中。

Django1.1版本的分发

from django.conf.urls import url,include

例子:

总路由:

  • -from django.conf.urls import include
  • -url(r'^blog/',include('blog.urls')),
  • -url(r'^app01/',include('app01.urls')),

各自路由配置url

  • app01--url(r'^publish/$', views.publish,name='app01_test'),
  • blog--url(r'^blogtest/$', views.test,name='blog_test'),

路由分发使用的是include()方法,需要提前导入,他的参数是转发目的地地路径的字符串。

重点:总路由后面不能加 $

两个不同的app,在各自的urlconf中为某一条url取了相同的name,这就会带来麻烦。为了解决这个问题,又引出了下面的命名空间。

八、命名空间

由于name没有作用域,Django在反解URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,立即返回。URL命名空间可以保证反查到唯一的URL,即使不同的app使用相同的URL名称。

示例:

urls.py

url(r'^blog/',include('blog.urls')),
url(r'^app01/',include('app01.urls')),

blog的urls.py

url(r'^blogtest/$', views.test,name='test'),

app01的urls.py

url(r'^publish/$', views.publish,name='test'),

blog的视图函数

def test(request):
  url=reverse('test')
  return HttpResponse('blog test)

app01的视图函数

def test(request):
  url=reverse('test')
  return HttpResponse('app01 test)

无论如何找index都是找的app01的index。

解决方法:在总路由分发的时候指定名称空间,实现命名空间的做法很简单,在urlconf文件中添加 namespace='xxx' 即可。

url(r'^blog/',include('blog.urls',namespace='blog')),
url(r'^app01/',include('app01.urls',namespace='app01')),

在视图函数反向解析的时候,指定是哪个名称空间下的

url = reverse('blog:test')

在模板里也指定是

{% url 'blog:test'%}

不是很推荐使用名称空间,推荐的是在子路由的name中加入app的前缀

url(r'^publish/$', views.publish,name='app01_test'),

九、伪静态

和真静态URL类似。他是通过伪静态规则把动态URL伪装成静态网址。

在urls.py文件中自己添加匹配 .html

url(r'^book/(?P<id>\d+.html)',views.book),

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python3实现生成随机密码的方法
Aug 23 Python
python 添加用户设置密码并发邮件给root用户
Jul 25 Python
python爬虫入门教程--正则表达式完全指南(五)
May 25 Python
python TCP Socket的粘包和分包的处理详解
Feb 09 Python
深入浅析python 中的匿名函数
May 21 Python
python数据类型之间怎么转换技巧分享
Aug 20 Python
python求质数列表的例子
Nov 24 Python
Python zip函数打包元素实例解析
Dec 11 Python
使用Python脚本从文件读取数据代码实例
Jan 19 Python
Django搭建项目实战与避坑细节详解
Dec 06 Python
PyQt5实现多张图片显示并滚动
Jun 11 Python
详细介绍python操作RabbitMq
Apr 12 Python
Python求两个圆的交点坐标或三个圆的交点坐标方法
Nov 07 #Python
在Python中分别打印列表中的每一个元素方法
Nov 07 #Python
对python中数组的del,remove,pop区别详解
Nov 07 #Python
对Python中plt的画图函数详解
Nov 07 #Python
python使用matplotlib绘制热图
Nov 07 #Python
Django objects的查询结果转化为json的三种方式的方法
Nov 07 #Python
Python将一个Excel拆分为多个Excel
Nov 07 #Python
You might like
Get或Post提交值的非法数据处理
2006/10/09 PHP
php 随机记录mysql rand()造成CPU 100%的解决办法
2010/05/18 PHP
解析php安全性问题中的:Null 字符问题
2013/06/21 PHP
php中sql注入漏洞示例 sql注入漏洞修复
2014/01/24 PHP
PHP自动生成表单代码分享
2015/06/19 PHP
JavaScript 应用类库代码
2008/06/02 Javascript
js 效率组装字符串 StringBuffer
2009/12/23 Javascript
JQUERY实现左侧TIPS滑进滑出效果示例
2013/06/27 Javascript
JavaScript中读取和保存文件实例
2014/05/08 Javascript
JS实现仿雅虎首页快捷登录入口及导航模块效果
2015/09/19 Javascript
Node.js的MongoDB驱动Mongoose基本使用教程
2016/03/01 Javascript
微信小程序 122100版本更新问题解决方案
2016/12/22 Javascript
jQuery.cookie.js实现记录最近浏览过的商品功能示例
2017/01/23 Javascript
jQuery的中 is(':visible') 解析及用法(必看)
2017/02/12 Javascript
vue-baidu-map 进入页面自动定位的解决方案(推荐)
2018/04/28 Javascript
微信小程序实现图片上传
2019/05/23 Javascript
JS数组属性去重并校验重复数据
2020/01/10 Javascript
ng-alain的sf如何自定义部件的流程
2020/06/12 Javascript
基于JS实现计算24点算法代码实例解析
2020/07/23 Javascript
Python判断变量是否为Json格式的字符串示例
2017/05/03 Python
python使用xlrd模块读取xlsx文件中的ip方法
2019/01/11 Python
Python 中PyQt5 点击主窗口弹出另一个窗口的实现方法
2019/07/04 Python
HTML5之SVG 2D入门10—滤镜的定义及使用
2013/01/30 HTML / CSS
HTML5 绘制图像(上)之:关于canvas元素引领下一代web页面的问题
2013/04/24 HTML / CSS
Html5移动端网页端适配(js+rem)
2021/02/03 HTML / CSS
Lookfantastic美国/加拿大:英国知名美妆购物网站
2019/03/27 全球购物
解释DataSet(ds) 和 ds as DataSet 的含义
2014/07/27 面试题
留学推荐信写作指南
2014/01/25 职场文书
技校个人求职信范文
2014/01/25 职场文书
幼儿园新年寄语
2014/04/03 职场文书
工地宣传标语
2014/06/18 职场文书
学生通报表扬范文
2015/05/04 职场文书
导游词之云南丽江古城
2019/09/17 职场文书
节约用水广告语60条
2019/11/14 职场文书
html实现随机点名器的示例代码
2021/04/02 Javascript
Apache Hudi数据布局黑科技降低一半查询时间
2022/03/31 Servers