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 相关文章推荐
python使用urllib2模块获取gravatar头像实例
Dec 18 Python
Python操作sqlite3快速、安全插入数据(防注入)的实例
Apr 26 Python
python如何查看系统网络流量的信息
Sep 12 Python
python爬虫入门教程--优雅的HTTP库requests(二)
May 25 Python
Python基于socket模块实现UDP通信功能示例
Apr 10 Python
python处理数据,存进hive表的方法
Jul 04 Python
python tkinter界面居中显示的方法
Oct 11 Python
python requests post多层字典的方法
Dec 27 Python
简单易懂Pytorch实战实例VGG深度网络
Aug 27 Python
django 扩展user用户字段inlines方式
Mar 30 Python
Django-migrate报错问题解决方案
Apr 21 Python
什么是python类属性
Jun 10 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
php下防止单引号,双引号在接受页面转义的设置方法
2008/09/25 PHP
深入密码加salt原理的分析
2013/06/06 PHP
PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
2014/07/08 PHP
js活用事件触发对象动作
2008/08/10 Javascript
javascript 基础篇2 数据类型,语句,函数
2012/03/14 Javascript
jquery实现瀑布流效果分享
2014/03/26 Javascript
windows8.1+iis8.5下安装node.js开发环境
2014/12/12 Javascript
微信小程序实现锚点定位楼层跳跃的实例
2017/05/18 Javascript
AngularJS中scope的绑定策略实例分析
2017/10/30 Javascript
基于$.ajax()方法从服务器获取json数据的几种方式总结
2018/01/31 Javascript
jQuery UI实现动画效果代码分享
2018/08/19 jQuery
layer更改皮肤的实现方法
2019/09/11 Javascript
Node.js中console.log()输出彩色字体的方法示例
2019/12/01 Javascript
js实现查询商品案例
2020/07/22 Javascript
[03:04]2018年国际邀请赛典藏宝瓶&莱恩声望物品展示 片尾有彩蛋
2018/06/04 DOTA
python中遍历文件的3个方法
2014/09/02 Python
对python的文件内注释 help注释方法
2018/05/23 Python
应用OpenCV和Python进行SIFT算法的实现详解
2019/08/21 Python
Python 异常处理Ⅳ过程图解
2019/10/18 Python
django之导入并执行自定义的函数模块图解
2020/04/01 Python
皇马官方商城:Real Madrid Store
2016/09/02 全球购物
美国殿堂级滑板、冲浪、滑雪服装品牌:Volcom(钻石)
2017/04/20 全球购物
个性化皮包、小袋、生活配件:Mon Purse
2019/03/26 全球购物
幼师自荐信
2013/10/26 职场文书
如何写求职信
2014/05/24 职场文书
个人简历自荐信
2014/06/26 职场文书
工程部经理岗位职责
2015/02/02 职场文书
办公室文员岗位职责
2015/02/04 职场文书
大学生村官工作总结2015
2015/04/09 职场文书
2016元旦晚会主持词
2015/07/01 职场文书
小学六一儿童节活动开幕词
2016/03/04 职场文书
导游词之永济鹳雀楼
2020/01/16 职场文书
Python 机器学习工具包SKlearn的安装与使用
2021/05/14 Python
pandas中DataFrame重置索引的几种方法
2021/05/24 Python
MySQL 使用索引扫描进行排序
2021/06/20 MySQL
ObjectMapper 如何忽略字段大小写
2021/06/29 Java/Android