django-url调度器-高级篇
我们在中级篇中学会了如何进行反向解析,但是有这样一个问题,在为 url 命名的时候,名字不能重复,否则会导致各种各样的问题。在 url 还少的时候保证不重名还是比较简单的,但是 url 多起来以后就比较难了。为了解决这样的问题,可以在 url 中加一个前缀。例如,我有一个 url 的名字叫做 'comment' ,此时,我可以为其加一个前缀,这个前缀通常是 app 名,例如:'myapp-comment'。
这也是django所推荐的命名方式,但是这样始终是治标不治本。此时,我们就要学习 django 中 url 命名空间了。
URL 命名空间
简介:
URL 命名空间允许你反查到唯一的命名 URL,即使在不同的应用中使用相同的 URL 名称。(也就是可以在不同的app中使用相同的名称,为有命名困难症的程序员带来了福音)
根据经验,第三方应用应该始终使用带命名空间的URL 。类似地,它还允许你在一个应用有多个实例部署的情况下反查URL。换句话讲,因为一个应用的多个实例共享相同的命名URL,命名空间将提供一种区分这些命名 URL 的方法。
在一个站点上,正确使用 URL 命名空间的 Django 应用可以部署多次。例如,django.contrib.admin 具有一个 AdminSite 类,它允许你很容易地部署多个管理站点的实例。在下面的例子中,我们将讨论在两个不同的地方部署教程中的polls 应用,这样我们可以为两种不同的用户(作者和发布者)提供相同的功能。
一个URL 命名空间有两个部分,它们都是字符串:
- 应用命名空间:
- 它表示正在部署的应用的名称。一个应用的每个实例具有相同的应用命名空间。例如,可以预见Django 的管理站点的应用命名空间是'admin'。
- 实例命名空间:
- 它表示应用的一个特定的实例。实例的命名空间在你的全部项目中应该是唯一的。但是,一个实例的命名空间可以和应用的命名空间相同。它用于表示一个应用的默认实例。例如,Django 管理站点实例具有一个默认的实例命名空间'admin'。
URL 的命名空间使用':' 操作符指定。例如,管理站点应用的主页使用'admin:index'。它表示'admin' 的一个命名空间和'index' 的一个命名URL。
命名空间也可以嵌套。命名URL'sports:polls:index' 将在命名空间'polls'中查找'index',而poll 定义在顶层的命名空间'sports' 中。
反查带命名空间的URL
我们在中级篇中了解到了 url 反查带来的变量,而在中级篇中,都是使用 name 进行反查,这里来看看如何对带命名空间的 url 进行反查。
例子:
from django.conf.urls import include, url urlpatterns = [
url(r'^author-polls/', include('polls.urls', namespace='author-polls', app_name='polls')),
url(r'^publisher-polls/', include('polls.urls', namespace='publisher-polls', app_name='polls')),
]
from django.conf.urls import url from . import views urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
...
]
反查的方法和中级篇的一样,在模板中:
{% url 'polls:index' %}
在基于类的视图的方法中:
reverse('polls:index', current_app=self.request.resolver_match.namespace)
另外,注意,在模板中的反查需要添加 request 的 current_app 属性,像这样:
def render_to_response(self, context, **response_kwargs):
self.request.current_app = self.request.resolver_match.namespace
return super(DetailView, self).render_to_response(context, **response_kwargs)
这时,会有同学有疑问了, polls 这个应用命名空间设置了两行呀,那 polls 下的 index 到底指的是哪个?
这个时候,就要看 django 的查找顺序了:
1.如果当前有实例,也就是说我们通过 url 访问到了某个处理函数,这个函数进行反向查询的时候,例如我访问的是:author-polls/ ,这个 url 对应的处理函数要进行反向解析,此时它要解析 'polls:detail'。那么将解析到 author-polls/(?P<pk>\d+)/$ 中,也就是有实例的优先在该实例空间中查询。
2.如果没有实例,但是有默认的实例空间,例如 app_name='polls',namespace='polls' ,和应用空间同名,这样的就叫做默认实例空间。在没有访问实例的时候,就匹配到默认实例空间中。
3.如果没有实例,也没有默认实例空间,那么谁是最后注册的就选谁,例子中的 namespace='publisher-polls' 就是最后一个注册的(也就是下面的)。
注意:
因为实例空间要是唯一的,所以使用 namespace:name 的模式应该也是唯一匹配的,例如这里的'author-polls:index' 将永远解析到 'author-polls' 实例的主页('publisher-polls' 类似)。
URL 命名空间和被包含的URLconf
被包含的URLconf 的命名空间可以通过两种方式指定。
首先,在你构造你的URL 模式时,你可以提供 应用 和 实例的命名空间给 include() 作为参数。例如
url(r'^polls/', include('polls.urls', namespace='author-polls', app_name='polls')),
这将包含 polls.urls 中定义的URL 到应用命名空间 'polls'中,其实例命名空间为'author-polls'。
其次,你可以include 一个包含嵌套命名空间数据的对象。如果你include() 一个url() 实例的列表,那么该对象中包含的URL 将添加到全局命名空间。然而,你还可以include() 一个3个元素的元组:
(<list of url() instances>, <application namespace>, <instance namespace>)
注意这里的应用命名空间和实例命名空间是相反的。
实例:
from django.conf.urls import include, url from . import views polls_patterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
] url(r'^polls/', include((polls_patterns, 'polls', 'author-polls'))),
这样会包含命名的URL模式进入到给定的应用和实例命名空间中。
与 url 相关的函数都在 django.conf.urls 中,下面看看里面都有哪些函数:
1. patterns(prefix, pattern_description, ...)
这是一个废弃了的方法,在 django1.8 之前,urlpatterns 变量是该函数的实例。
例如:
from django.conf.urls import patterns, url urlpatterns = patterns('',
url(r'^articles/([0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'news.views.month_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'news.views.article_detail'),
)
第一个参数是一个前缀,这里的所有表示处理函数的字符串都是以 'new.views' 开头的,所有可以改写成下面这种形式:
from django.conf.urls import patterns, url urlpatterns = patterns('news.views',
url(r'^articles/([0-9]{4})/$', 'year_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'month_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'article_detail'),
)
因为 patterns 是python的一个方法,而 python 中,一个方法最多接受 255 个参数,也就是说最多可以在一个 patterns 中写 255-1 个 url,虽然这一般不会有什么影响,因为我们可以通过 include 方法来分离 url,而且这个方法返回的是一个列表,所以可以通过列表拼接的方式,来扩展,例如:
urlpatterns = patterns('',
...
)
urlpatterns += patterns('',
...
)
所以也只是现在最多一次性创建多少个 url 而已。
但是这个方法还是在 1.8 中废弃了(当然你还可强行用,到 1.9.4 为止代码并没有被移除,以后的版本另算),以后直接使用 python 列表,列表中的元素是 url() 函数的实例就行了。而 python 的列表不限制长度,只看电脑的内存有没有足够的空间,所以也算是改进了。
2. static.static(prefix, view=django.views.static.serve, **kwargs)
如果你通过django的后台上传了一张图片,而你又想在前端显示它。一般而言 django 只提供了静态文件的支持(默认是 /static/ 开头的url请求都视为静态文件请求),而图片上传是通过 MEDIA_URL 来作为
请求的开头的,但是如果不做特殊设置,是无法显示的,此时,可以通过以下的方式:
from django.conf import settings
from django.conf.urls.static import static urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
这是老版本的写法,新版本中直接把函数放进列表中,作为列表中的一个元素就行。
注意:这里我们并没有为 view 传参,直接用默认的就行。
当然,这也只是在开发环境中使用,如果到了正式生产环境,这些东西还是老老实实用 web server ,例如Apache或者nginx之类的作为前方代理,django自带的 web 服务估计并发量在20左右就会挂掉,而且还不是守护进程,也就是说挂掉了不会重启,要多蛋疼有多蛋疼。
3. include(arg, namespace=None, app_name=None)
arg:可以接受一个字符串,表示被包含的模块在哪里;也可以接受一个列表,这个列表是被包含的 url() 的实例;还可以接受一个元祖,元祖的第一个元素是一个被包含的列表,第二个元素是该列表的应用空间名,第三个元素是实例空间名。
namespace : 实例命名空间
app_name : 应用命名空间
4. url(regex, view, kwargs=None, name=None, prefix='')
regex:要匹配的 url。
view:该 url 的处理函数,可以是一个表示函数位置的字符串, 也可以是一个函数的实例。
kwargs: 一个字典,表示传递多余的参数。
name : 为 url 进行命名。
prefix : if prefix: view = prefix + '.' + view 表示在 view 前加上前缀。
5.各种 handler:
django 自带错误处理视图:
handler400 = 'django.views.defaults.bad_request'
handler403 = 'django.views.defaults.permission_denied'
handler404 = 'django.views.defaults.page_not_found'
handler500 = 'django.views.defaults.server_error'
在触发相应的错误的时候,都会转向默认的处理函数,当然我们也可以重写它们,只有在 urls.py 中导入它们,并改写成我们自己的处理函数的字符串表示就可以了。
django-url调度器-高级篇的更多相关文章
- Django URL调度器
Django处理请求的流程 Django确定要使用的根URLconf模块.通常,这是ROOT_URLCONF设置的值,但如果传入 HttpRequest对象具有urlconf 属性(由中间件设置),则 ...
- Django 源码小剖: 更高效的 URL 调度器(URL dispatcher)
效率问题 django 内部的 url 调度机制说白了就是给一张有关匹配信息的表, 这张表中有着 url -> action 的映射, 当请求到来的时候, 一个一个(遍历)去匹配. 中, 则调用 ...
- Django 源码小剖: URL 调度器(URL dispatcher)
在刚开始接触 django 的时候, 我们尝试着从各种入门文档中创建一个自己的 django 项目, 需要在 mysite.urls.py 中配置 URL. 这是 django url 匹配处理机制的 ...
- URL 调度器(URL dispatcher)
URL 调度器(URL dispatcher) 在刚开始接触 django 的时候, 我们尝试着从各种入门文档中创建一个自己的 django 项目, 需要在 mysite.urls.py 中配置 UR ...
- django-url调度器-中级篇
在初级篇中,我们接触了: 1.url 的简单编写 2.两种传参的方式 3.捕获的参数总是字符串 4.为视图设置默认参数 …… 在中级篇中将更进一步. 包含其它的URLconfs 当网站非常大的时候,将 ...
- django url注册器组件, 响应器组件, 分页器组件
一.url注册器的使用 1.1导入模块 from django.urls import re_path, include from .serializer import views from rest ...
- django-url调度器-初级篇
Django 遵从 MVC 模型,并将其特色化为 MTV 模型.模型的核心是通过用户访问的 url 来指向处理的函数,而函数处理后返回相应的结果.所以url决定了用户访问的入口,另外表单处理的提交地址 ...
- Django url分发器
视图: 视图一般都写在app的views.py中.并且视图的第一个参数永远都是request(一个HttpRequest)对象.这个对象存储了请求过来的所有信息,包括携带的参数以及一些头部信息等.在视 ...
- django url调度
Django的url配置相同遵循着DRY(dont repeat yourself)的规则.下面都是官方文档的样例: 首先介绍的是Django怎样处理http的请求: 1.在setting里定义ROO ...
随机推荐
- Xcode引入外界文件时选Create groups 或 Create folder references的区别
一.使用Create groups 我们在项目中可以手动添加一个groups(右键点击选择New Group),但是手动添加的groups实际上并不会存在于项目的目录中,被添加进groups中的文件仍 ...
- NopCommerce 3.80框架研究(一) 数据访问与持久化
NopCommerce 是一个国外的开源电商系统.3.80版本使用EF6.0 和.Net Framework 4.5.1 并引入了Autofac , Autofac是一款IOC框架,比较于其他的IOC ...
- 解决setInterval计时器不准的问题
在js中如果打算使用setInterval进行倒数,计时等功能,往往是不准确的,因为setInterval的回调函数并不是到时后立即执行,而是等系统计算资源空闲下来后才会执行.而下一次触发时间则是在s ...
- python中get、post数据
方法一:urllib2 参考:http://www.cnblogs.com/chenzehe/archive/2010/08/30/1812995.html post: #!/usr/bin/pyth ...
- 学习练习 java 输入输出流练习2
编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt p ...
- 洛谷P1268 树的重量
P1268 树的重量 85通过 141提交 题目提供者该用户不存在 标签树形结构 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 有这种情况吗!!!! 题意似乎有问题 题目描述 树可以用来表 ...
- cordova 开发属于自己的插件---android
还是需要开发出自己的插件的... 我的cordova version is 4.0.0 1.需要新建一个文件夹为 myplugin 1.1在myplugin文件夹下 新建 plugin.xml文件 ...
- hql 关联查询
HQL 带的连接语句只能是实体与 该实体的属性 进行连接 其意义就是为了优化(通过延迟加载查询关联的属性)需要进行配置 from A left join A.B where (b.flag is nu ...
- 织梦dedecms调用栏目的SEO标题、描述、关键字的方法
调用SEO标题:<title>{dede:field.title/}_{dede:field.seotitle /}-{dede:global.cfg_webname/}</titl ...
- 【.NET】MD5的用法(对文件、字符串)
using System;using System.IO;using System.Security.Cryptography;using System.Text;namespace ConsoleA ...