一、路由转发

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

例如,下面是Django网站本身的URLconf节选。 它包含许多其它URLconf:

from django.conf.urls import include, url

urlpatterns = [
# ... 忽略 ...
url(r'^community/', include('django_website.aggregator.urls')),
url(r'^contact/', include('django_website.contact.urls')),
# ... 忽略 ...
]

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

注意,这个例子中的正则表达式没有包含$(字符串结束匹配符),但是包含一个末尾的斜杠。 每当Django 遇到include()(来自django.conf.urls.include())时,它会去掉URL中匹配的部分并将剩下的字符串发送给include的URLconf做进一步处理,也就是转发到二级路由去。

另外一种转发其它URL模式的方式是使用一个url()实例的列表。 例如,下面的URLconf:

from django.conf.urls import include, url

from apps.main import views as main_views
from credit import views as credit_views extra_patterns = [
url(r'^reports/$', credit_views.report),
url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),
url(r'^charge/$', credit_views.charge),
] urlpatterns = [
url(r'^$', main_views.homepage),
url(r'^help/', include('apps.help.urls')),
url(r'^credit/', include(extra_patterns)),
]

在此示例中,/credit/reports/URL将由credit_views.report()视图处理。这种做法,相当于把二级路由模块内的代码写到根路由模块里一起了,不是很推荐。

再看下面的URLconf:

from django.conf.urls import url
from . import views urlpatterns = [
url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/history/$', views.history),
url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/edit/$', views.edit),
url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/discuss/$', views.discuss),
url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/permissions/$', views.permissions),
]

上面的路由写得不好,我们可以改进它,只需要声明共同的路径前缀一次,并将后面的部分分组转发:

from django.conf.urls import include, url
from . import views urlpatterns = [
url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/', include([
url(r'^history/$', views.history),
url(r'^edit/$', views.edit),
url(r'^discuss/$', views.discuss),
url(r'^permissions/$', views.permissions),
])),
]

这样就优雅多了,也清爽多了,但前提是你要理解这种做法。

二、捕获参数

被转发的URLconf会收到来自父URLconf捕获的所有参数,看下面的例子:

# In settings/urls/main.py
from django.conf.urls import include, url urlpatterns = [
url(r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
] # In foo/urls/blog.py
from django.conf.urls import url
from . import views urlpatterns = [
url(r'^$', views.blog.index),
url(r'^archive/$', views.blog.archive),
]

在上面的例子中,捕获的"username"变量将被传递给include()指向的URLconf,再进一步传递给对应的视图。

三、嵌套参数

正则表达式允许嵌套参数,Django将解析它们并传递给视图。当反查时,Django将尝试填满所有外围捕获的参数,并忽略嵌套捕获的参数。 考虑下面的URL模式,它带有一个可选的page参数:

from django.conf.urls import url

urlpatterns = [
url(r'blog/(page-(\d+)/)?$', blog_articles), # bad
url(r'comments/(?:page-(?P<page_number>\d+)/)?$', comments), # good
]

两个模式都使用嵌套的参数,其解析方式是:例如blog/page-2/将匹配page-2/并带有两个位置参数blog_articles和2。第二个comments的模式将匹配page_number并带有一个值为2的关键字参数comments/page-2/。这个例子中外围参数是一个不捕获的参数(?:...)。

blog_articles视图需要最外层捕获的参数来反查,在这个例子中是comments或者没有参数,而page-2/可以不带参数或者用一个page_number值来反查。

四、向视图传递额外的参数

URLconfs具有一个钩子(hook),允许你传递一个Python字典作为额外的关键字参数给视图函数。

像这样:

from django.conf.urls import url
from . import views urlpatterns = [
url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

在上面的例子中,对于/blog/2005/请求,Django将调用views.year_archive(request, year='2005', foo='bar')。理论上,你可以在这个字典里传递任何你想要的传递的东西。但是要注意,URL模式捕获的命名关键字参数和在字典中传递的额外参数有可能具有相同的名称,这会发生冲突,要避免。

五、传递额外的参数给include()

类似上面,也可以传递额外的参数给include()。参数会传递给include指向的urlconf中的每一行。

例如,下面两种URLconf配置方式在功能上完全相同:

配置一:

# main.py
from django.conf.urls import include, url urlpatterns = [
url(r'^blog/', include('inner'), {'blogid': 3}),
] # inner.py
from django.conf.urls import url
from mysite import views urlpatterns = [
url(r'^archive/$', views.archive),
url(r'^about/$', views.about),
]

配置二:

# main.py
from django.conf.urls import include, url
from mysite import views urlpatterns = [
url(r'^blog/', include('inner')),
] # inner.py
from django.conf.urls import url urlpatterns = [
url(r'^archive/$', views.archive, {'blogid': 3}),
url(r'^about/$', views.about, {'blogid': 3}),
]

注意,只有当你确定被include的URLconf中的每个视图都接收你传递给它们的额外的参数时才有意义,否则其中一个以上视图不接收该参数都将导致错误异常。

django路由转发的更多相关文章

  1. Django路由

    一.路由流程 1. 用户浏览器发出请求后,通过根url设置,去找urlpattern变量.在setting.py中对 ROOT_URLCONF进行配置,以确定根URLconf(URL configur ...

  2. django 路由层(反向解析)03

    目录 ORM表关系建立 Django请求生命周期流程图 urls.py 路由层 无名分组 有名分组 反向解析 无名分组的反向解析 有名分组的反向解析 以编辑功能为例 路由分发 名称空间 伪静态 虚拟环 ...

  3. 网络-数据包在路由转发过程中MAC地址和IP地址,变与不变

    关于MAC地址和IP地址在传输过程中变与不变的问题: 结论:MAC地址在同一个广播域传输过程中是不变的,在跨越广播域的时候会发生改变的:而IP地址在传输过程中是不会改变的(除NAT的时候),总结为 路 ...

  4. 转:数据包经由路由转发时源、目的IP地址及MAC地址变化情况

    数据包经由路由转发时源.目的IP地址及MAC地址变化情况.  IP数据包经由路由转发的时候源ip,目的ip,源MAC,目的mac是否发生改变,如何改变?   A—–(B1-B2)—–(C1-C2)—— ...

  5. Django路由系统

    django路由系统 简而言之,django的路由系统作用就是使views里面处理数据的函数与请求的url建立映射关系.使请求到来之后,根据urls.py里的关系条目,去查找到与请求对应的处理方法,从 ...

  6. 使用linux系统做路由转发

    使用linux系统(PC机)做路由转发 关键字:linux,Fedora,route,iptables,ip_forward 最近做网络实验,在实验过程中需要用到linux的转发功能,但是遇到一些问题 ...

  7. Django 路由系统

    Django 路由系统 基本格式 from django.conf.urls import url urlpatterns = [ url(正则表达式, views视图函数,参数,别名), ] 参数说 ...

  8. 基于嵌入式linux路由转发功能的实现

    环境 arm7开发板, uclinux系统,kernel version: linux-2.4.x arm芯片的单网卡双网口设备,eth0 WAN口 ipaddr 192.168.9.61 eth0: ...

  9. 前端跨域问题的总结&&nodejs 中间层的路由转发

    前后端交互的时候,跨域是避不开的问题. 总结就是如下: 1.Cors 我在做前后端分离的时候,会采用cors 的方法:便于其他源的调用接口,这个可以设置成任意的源头,也可以允许指定的源头. 下面的是n ...

随机推荐

  1. [LeetCode] 198. House Robber _Easy tag: Dynamic Programming

    You are a professional robber planning to rob houses along a street. Each house has a certain amount ...

  2. Windows多线程基础

    进程与线程基础 程序: 计算机指令的集合,以文件的形式存储在磁盘上 进程: 正在运行是程序实例,以是一个程序在其自身的地址空间的一次执行活动.进程有一个进程管理的内核对象和地址空间组成. 线程: 程序 ...

  3. c++实现web服务框架

    lamada表达式 声明一个返回数组指针的函数            返回指针数组的函数形式如下所示:    括号必须存在 注意->后不能加() Lambda表达式  

  4. linux locate

    locate命令查找文件比find速度快很多,locate是在linux下实现快速查找文件的工具.相应的windows下有everything功能也很强大. [root@wuzhigang lib]# ...

  5. chrome浏览器使用

    1.如何打开多个历史网页.这个需求是这样的,有时候开了多个网页查找资料,但是又还没有做完,然后又需要重启电脑.显然重启电脑后再开启浏览器,一般都是显示浏览器的主页了,上次开的那些网页全部在历史记录里面 ...

  6. Object-C-selector

    Shape *shape=[[Shape alloc]init]; //[shape draw] SEL selDraw=@selector(draw); [shape performSelector ...

  7. Repeater 控件使用总结

      关于Repeater控件使用的一些总结,希望能对将来有机会看到这篇日志的同事有所帮助.也是为了在自己开发有所遗忘的时候能够参考一下.前言:Repeater是一个迭代控件,什么是迭代控件呢?书本上的 ...

  8. Linux启动vi编辑器时提示E325: ATTENTION解决方案

    Linux启动vi编辑器时提示E325: ATTENTION解决方案 Vi编辑器是Linux的文本编辑器,在Linux系统的运用非常广泛,不少朋友在打开Vi编辑器的时候提示E325: ATTENTIO ...

  9. 20145227鄢曼君《网络对抗》Web安全基础实践

    20145227鄢曼君<网络对抗>Web安全基础实践 实验后回答问题 1.SQL注入攻击原理,如何防御? SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是 ...

  10. LM2596、LM2576

    找来的资料,参考一下,震荡频率不一样,最大输入电压不一样. LM2576系列是的3A电流输出降压开关型集成稳压电路, ●最大输出电流:3A; ●振荡频率:52kHz; ●转换效率:75%-88%(不同 ...