您的位置:首页 > 编程语言 > Go语言

Django的URLConf技巧

2009-01-05 23:19 447 查看
1、伪造捕捉到的URLConf
如果有匹配某个模式的一推试图,以及一个并不匹配这个模式的但它的试图逻辑是一样的URL。这种情况下,可以伪造URL值的捕捉,
这主要通过使用额外URLConf参数,使得这个多出来的URL一样使用试图。

例如,你有可能有一个显示某一个特定日子的某些数据的应用,URL类似这样:
/mydata/jan/01/
/mydata/jan/02/
/mydata/jan/03/
# ...
/mydata/dec/30/
/mydata/dec/31/

太简单了,你可以再URLconf中捕捉这些值,使用组命名
urlpatterns = patterns('',
(r'^mydata/(?P<Month>d{2})/(?P<Day>d{2})/$',views.my_view),
)
然后试图看起来可能是这样
def my_view(request,month,day):
#...
这种简单方法很直接,没什么特别技术,问题如果你想添加一个使用my_view试图的URL但
它每包含一个Month和/或者Day。
比如你可能响增加一个这样的URL /mydata/birthday/. 这个URL等价于/mydata/jan/06,
这时候你可以使用额外参数来达到
urlpatterns = patterns('',
(r'^mydata/birthday/$',views.my_view,{'Month':'jan','Day':'06'}),
(r'^mydata/(?P<Month>d{2})/(?P<Day>d{2})/$',views.my_view),
)

在这里最帅的地方莫过于你根本不用改变你的视图函数。视图函数只会关心它 获得 了 month 和 day 参数,
它不会去管这些参数到底是捕捉回来的还是被额外提供的。

2.了解捕捉值和额外参数之间的优先级
额外参数优先级高于捕捉值参数
例如
from django.conf.urls.defaults import *

urlpatterns = patterns('',
(r'^mydata/(?P<id>/d+)/$', views.my_view, {'id': 3}),
)
这里无论正则表达式匹配的Id值是多少,都会当做Id=3处理。
所以在开发过程中,一定注意避免出现上诉情况

3、短路逻辑
URLConf采用自上而下的匹配方式。
例如一个视图
urlpatterns = patterns('',
# ...
('^([^/]+)/([^/]+)/add/$', 'django.contrib.admin.views.main.add_stage'),
# ...
)
它将匹配像 /myblog/entries/add/ 和 /auth/groups/add/ 这样的URL,然而,对于用户对象的添加页面( /auth/user/add/ )是个特殊情况
我们可以在视图里判断一下而处理

视图:
def add_stage(request,app_moudle,moudle_name):
if app_moudle=='auth' and moudle_name=='user':
# 处理
else:
#处理
这种方法固然实现了我们的目的,但是他看上去很不优雅,我们应该将判断逻辑放到URLconf中,而不是视图中。
这里我们利用“短路逻辑”处理
urlpatterns = patterns('',
# ...
('^auth/user/add/$', 'django.contrib.admin.views.auth.user_add_stage'),
('^([^/]+)/([^/]+)/add/$', 'django.contrib.admin.views.main.add_stage'),
# ...
)

4、包含其他URLconf

如果你试图让你的代码用在多个基于Django的站点上,你应该考虑将你的URLconf以包含的方式来处理。

在任何时候,你的URLconf都可以包含其他URLconf模块。对于根目录是基于一系列URL的站点来说,这是必要的。例如下面的,URLconf包含了其他URLConf:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
(r'^weblog/', include('mysite.blog.urls')),
(r'^photos/', include('mysite.photos.urls')),
(r'^about/$', 'mysite.views.about'),
)

这里有个很重要的地方:例子中的指向 include() 的正则表达式并 不 包含一个 $ (字符串结尾匹配符),但是包含了一个斜杆。每当Django遇到 include() 时,它将截断匹配的URL,并把剩余的字符串发往包含的URLconf作进一步处理。

继续看这个例子,这里就是被包含的URLconf mysite.blog.urls :

from django.conf.urls.defaults import *

urlpatterns = patterns('',
(r'^(/d/d/d/d)/$', 'mysite.blog.views.year_detail'),
(r'^(/d/d/d/d)/(/d/d)/$', 'mysite.blog.views.month_detail'),
)

通过这两个URLconf,下面是一些处理请求的例子:

*

/weblog/2007/ :在第一个URLconf中,模式 r'^weblog/' 被匹配。因为它是一个 include() ,Django将截掉所有匹配的文本,在这里是 'weblog/' 。URL剩余的部分是 2007/ , 将在 mysite.blog.urls 这个URLconf的第一行中被匹配到。

*

/weblog//2007/ :在第一个URLconf中,模式 r'^weblog/' 被匹配。因为它是一个 include() ,Django将截掉所有匹配的文本,在这里是 'weblog/' 。URL剩余的部分是 /2007/ (开头有一个斜杠),将不会匹配 mysite.blog.urls 中的任何URLconf。

*

/about/ : 这个匹配第一个URLconf中的 mysite.views.about 视图。只是为了示范你可以混合 include() patterns和 non-include() patterns在一起使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: