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中optionParser模块的使用方法实例教程
Aug 29 Python
Python解析nginx日志文件
May 11 Python
说一说Python logging
Apr 15 Python
关于Python中异常(Exception)的汇总
Jan 18 Python
python删除过期log文件操作实例解析
Jan 31 Python
python之pexpect实现自动交互的例子
Jul 25 Python
flask的orm框架SQLAlchemy查询实现解析
Dec 12 Python
python获取依赖包和安装依赖包教程
Feb 13 Python
使用Keras加载含有自定义层或函数的模型操作
Jun 10 Python
matplotlib基础绘图命令之errorbar的使用
Aug 13 Python
关于Python 解决Python3.9 pandas.read_excel(‘xxx.xlsx‘)报错的问题
Nov 28 Python
Python获取指定日期是"星期几"的6种方法
Mar 13 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
收音机的保养
2021/03/01 无线电
php function用法如何递归及return和echo区别
2014/03/07 PHP
PHP防止表单重复提交的几种常用方法汇总
2014/08/19 PHP
PHP中使用CURL获取页面title例子
2015/01/07 PHP
PHP curl模拟登录带验证码的网站
2015/11/30 PHP
php集成动态口令认证
2016/07/21 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
2016/09/22 PHP
thinkphp5修改view到根目录实例方法
2019/07/02 PHP
JavaScript来实现打开链接页面的简单实例
2016/06/02 Javascript
好好了解一下Cookie(强烈推荐)
2016/06/14 Javascript
详细谈谈javascript的对象
2016/07/31 Javascript
javascript实现的左右无缝滚动效果
2016/09/19 Javascript
JavaScript中捕获与冒泡详解及实例
2017/02/03 Javascript
微信小程序实现tab页面切换功能
2018/07/13 Javascript
总结javascript三元运算符知识点
2018/09/28 Javascript
JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例
2019/01/29 Javascript
Jquery ajax书写方法代码实例解析
2020/06/12 jQuery
layui使用及简单的三级联动实现教程
2020/12/01 Javascript
Python实现读取TXT文件数据并存进内置数据库SQLite3的方法
2017/08/08 Python
Java编程迭代地删除文件夹及其下的所有文件实例
2018/02/10 Python
Python多线程中阻塞(join)与锁(Lock)使用误区解析
2018/04/27 Python
使用CodeMirror实现Python3在线编辑器的示例代码
2019/01/14 Python
Pycharm运行加载文本出现错误的解决方法
2019/06/27 Python
python3 中的字符串(单引号、双引号、三引号)以及字符串与数字的运算
2019/07/18 Python
爬虫代理池Python3WebSpider源代码测试过程解析
2019/12/20 Python
Django Session和Cookie分别实现记住用户登录状态操作
2020/07/02 Python
AmazeUI 面板的实现示例
2020/08/17 HTML / CSS
Baby Tulai澳大利亚:美国婴儿背带品牌
2018/10/15 全球购物
荷兰领先的百货商店:De Bijenkorf
2018/10/17 全球购物
机械专业应届生求职信
2013/12/12 职场文书
安全教育感言
2014/03/04 职场文书
门市房租房协议书
2014/12/04 职场文书
艺术节开幕词
2015/01/28 职场文书
原生JavaScript实现简单五子棋游戏
2021/06/28 Javascript
openstack中的rpc远程调用的方法
2021/07/09 Python
《群青的幻想曲》京力秋树角色PV公开
2022/04/08 日漫