Django--URLconf配置技巧

本章我们将对视图和URL配置使用一些高超的小技巧。

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:申请域名、虚拟空间、营销软件、网站建设、西丰网站维护、网站推广。

【流线型化函数导入(streamlining)】

方法一:传统方法

from django.conf.urls.defaults import *
from mysite.views import hello, current_datetime, hours_ahead

urlpatterns = patterns('',
    (r'^hello/$', hello),
    (r'^time/$', current_datetime),
    (r'^time/plus/(\d{1,2})/$', hours_ahead),
)

方法二:导入views函数,维护较简单,针对import的视图模块

from django.conf.urls.defaults import *
**from mysite import views**

urlpatterns = patterns('',
    (r'^hello/$', views.hello'),
    (r'^time/$', views.current_datetime ),
    (r'^time/plus/(d{1,2})/$', views.hours_ahead ),
)

方法三:导入模块名和视图函数名,注意用引号括起来

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^hello/$', 'mysite.views.hello' ),
    (r'^time/$', 'mysite.views.current_datetime' ),
    (r'^time/plus/(d{1,2})/$', 'mysite.views.hours_ahead' ),
)

方法四:提取公共视图前缀,不要再前缀后面和视图字符串前面放点号,django会自动处理

from django.conf.urls.defaults import *

urlpatterns = patterns('mysite.views' ,
    (r'^hello/$', 'hello' ),
    (r'^time/$', 'current_datetime' ),
    (r'^time/plus/(d{1,2})/$', 'hours_ahead' ),
)

方法四(2):如果我们URLconf没有一个公共前缀时呢?如下

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^hello/$', 'mysite.views.hello'),
    (r'^time/$', 'mysite.views.current_datetime'),
    (r'^time/plus/(\d{1,2})/$', 'mysite.views.hours_ahead'),
    (r'^tag/(\w+)/$', 'weblog.views.tag'),
)

解决:整个框架关注的是urlpatterns模块级别的变量,patterns返回对象是可相加的。

from django.conf.urls.defaults import *

urlpatterns = patterns('mysite.views',
    (r'^hello/$', 'hello'),
    (r'^time/$', 'current_datetime'),
    (r'^time/plus/(\d{1,2})/$', 'hours_ahead'),
)
urlpatterns += patterns('weblog.views',
    (r'^tag/(\w+)/$', 'tag'),
)

特例:django调试模式下修改URLconf的行为技术,链接debuginfo只在DEBUG配置项为True时才有效。

from django.conf import settings
from django.conf.urls.defaults import *

from mysite import views
urlpatterns = patterns('',
      .....   
    ) 
if settings.DEBUG:
    urlpatterns += patterns('',
        (r'^debuginfo/$', views.debug),
    )

【url的命名法匹配模式】

方法一:使用命名组,好比python函数中位置参数和关键字参数的对应关系,其语法 (?P<组名字>匹配模式)。

## 传统方法
from django.conf.urls.defaults import *
from mysite import views

urlpatterns = patterns('',
    (r'^articles/(\d{4})/$', views.year_archive),
    (r'^articles/(\d{4})/(\d{2})/$', views.month_archive),
)

## 使用命名组
from django.conf.urls.defaults import *
from mysite import views

urlpatterns = patterns('',
    (r'^articles/(?P\d{4})/$', views.year_archive),
    (r'^articles/(?P\d{4})/(?P\d{2})/$', views.month_archive),
)

为了区分它们的区别,以请求/archive/2016/12为例,函数都进行了怎样的调用?
前者:month_archive(request, '2016', '12')
后者:month_archive(request, year='2016', month='12')
缺点:虽然这样可读性强了,而且更准确了,但是冗余性也变差了;而且一个URLconf模式中不允许同时存在命名组和非命名组格式,优先顺序:命名组>非命名组>关键字传递额外参数。

【传递额外参数信息】

在我们写的视图函数中,我们会发现有好多视图函数类似,但又有不同,我们怎么样才能将它写的更简洁,原始模板如下:

# urls.py
from django.conf.urls.defaults import *
from mysite import views

urlpatterns = patterns('',
    (r'^foo/$', views.foo_view),
    (r'^bar/$', views.bar_view),
)

# views.py
from django.shortcuts import render_to_response
from mysite.models import MyModel

def foo_view(request):
    m_list = MyModel.objects.filter(is_new=True)
    return render_to_response('template1.html', {'m_list': m_list})
def bar_view(request):
    m_list = MyModel.objects.filter(is_new=True)
    return render_to_response('template2.html', {'m_list': m_list})

方法一:添加if 判断,缺点还是把url耦合到代码里了,更改url的话还得去改视图函数。

# views.py
from django.shortcuts import render_to_response
from mysite.models import MyModel
def foobar_view(request, url):
    m_list = MyModel.objects.filter(is_new=True)
    if url == 'foo':
        template_name = 'template1.html'
    elif url == 'bar':
        template_name = 'template2.html'
    return render_to_response(template_name, {'m_list': m_list})

方法二:URLconf中包含第三个位置参数:关键字参数

# urls.py
from django.conf.urls.defaults import *
from mysite import viewsurlpatterns = patterns('',
    (r'^foo/$', views.foobar_view, {'template_name': 'template1.html'}),
    (r'^bar/$', views.foobar_view, {'template_name': 'template2.html'}),
)

# views.py
from django.shortcuts import render_to_response
from mysite.models import MyModel
def foobar_view(request, template_name):
    m_list = MyModel.objects.filter(is_new=True)
    return render_to_response(template_name, {'m_list': m_list})

举例:我们要访问如下规则的url

/mydata/jan/01/
/mydata/jan/02/
/mydata/jan/03/
# ...
/mydata/dec/30/
/mydata/dec/31/
我们可以设置URLconf 和 视图函数如下:

urlpatterns = patterns('',

    (r'^mydata/(?P\w{3})/(?P\d\d)/$', views.my_view),

)
def my_view(request, month, day):

    # ....
但当如果我们想增加访问一个/mydata/birthday/的url,正常我们要给他一个视图函数,但我们可以用上面传递额外参数解决
urlpatterns = patterns('',

    (r'^mydata/birthday/$', views.my_view, {'month': 'jan', 'day': '06'}),

    (r'^mydata/(?P\w{3})/(?P\d\d)/$', views.my_view),

)

【include其他URLconf】

有时我们希望我们的代码用于多个django站点,于是我们就要考虑将我们的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'),
)

注:在包含其他urls的url没有$符,但包含有/,他的意思是当django遇到include,它将截断匹配的URL,把剩余的字符串发往包含的URLconf进一步处理。
比如我们访问/weblog/2007/ weblog被此URLconf匹配,/ 截断的2007就交给了包含的URLconf中的urls。
1、捕获的参数与include

# root urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
    (r'^(?P\w+)/blog/', include('foo.urls.blog')),
)

# foo/urls/blog.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
    (r'^$', 'foo.views.blog_index'),
    (r'^archive/$', 'foo.views.blog_archive'),
)

本例中,被捕获的username变量将传递给被包含的URLconf,进而传递给那个URLconf中每一个视图函数。
2、额外的URLconf与include
就像上边提到的,URLconf有一个第三位置的参数,用字典表示,即下面两个配置时等效的:

# urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
    (r'^blog/', include('inner'), {'blogid': 3}),
)

# inner.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
    (r'^archive/$', 'mysite.views.archive'),
    (r'^about/$', 'mysite.views.about'),
    (r'^rss/$', 'mysite.views.rss'),
)
# urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
    (r'^blog/', include('inner')),
)

# inner.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
    (r'^archive/$', 'mysite.views.archive', {'blogid': 3}),
    (r'^about/$', 'mysite.views.about', {'blogid': 3}),
    (r'^rss/$', 'mysite.views.rss', {'blogid': 3}),
)

分享标题:Django--URLconf配置技巧
本文网址:http://myzitong.com/article/poegsi.html