第八章 高级视图和URL配置Word下载.docx
- 文档编号:19444396
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:18
- 大小:26.50KB
第八章 高级视图和URL配置Word下载.docx
《第八章 高级视图和URL配置Word下载.docx》由会员分享,可在线阅读,更多相关《第八章 高级视图和URL配置Word下载.docx(18页珍藏版)》请在冰豆网上搜索。
但随着Django应用变得复杂,它的URLconf也在增长,并且维护这些导入可能使得管理变麻烦。
(对每个新的view函数,你不得不记住要导入它,并且如果采用这种方法导入语句将变得相当长。
)有可能通过导入views模块本身来避免这个麻烦。
这个URLconf示例同上一个是等价的:
frommysiteimportviews
views.current_datetime),
views.hours_ahead),
views.hours_behind),
views.now_in_chicago),
views.now_in_london),
Django还提供了另一种方法可以在URLconf中为某个特别的模式指定视图函数:
你可以传入一个包含模块名和函数名的字符串,而不是函数对象本身。
继续示例:
'
mysite.views.current_datetime'
),
mysite.views.hours_ahead'
mysite.views.hours_behind'
mysite.views.now_in_chicago'
mysite.views.now_in_london'
(注意视图名前后的引号。
应该使用带引号的'
而不是mysite.views.current_datetime。
使用这个技术,就不必导入视图函数了;
Django会在第一次需要它时导入合适的视图函数,根据字符串所描述的视图函数的名字和路径。
当使用字符串技术时,你可以采用更简化的方式:
提取出一个公共视图前缀。
在我们的URLconf例子中,每一个视图字符串都是以'
mysite.views'
开始的,造成过多的输入。
我们可以提取出公共前缀然后把它作为第一个参数传给patterns(),如:
current_datetime'
hours_ahead'
hours_behind'
now_in_chicago'
now_in_london'
注意既不要在前缀后面跟着一个点号("
."
),也不要在视图字符串前面放一个点号。
Django会自动处理它们。
牢记这两种方法,哪种更好一些呢?
这取决于你的个人编码习惯和需要。
字符串方法的好处如下:
更紧凑,因为不需要你导入视图函数
如果你的视图函数存在于几个不同的Python模块的话,它可以使得URLconf更易读和管理。
函数对象方法的好处如下:
更容易对视图函数进行包装(wrap)。
参见本章后面的《包装视图函数》一节。
更Pythonic,更符合Python的传统,如把函数当成对象传递。
两个方法都是有效的,甚至你可以在同一个URLconf中混用它们。
决定权在你。
使用多个视图前缀
在实践中,如果你使用字符串技术,特别是当你的URLconf中没有一个公共前缀时,你最终可能混合视图。
然而,你仍然可以利用视图前缀的简便方式来减少重复。
只要增加多个patterns()对象,象这样:
旧的:
^/?
$'
mysite.views.archive_index'
^(\d{4})/([a-z]{3})/$'
mysite.views.archive_month'
^tag/(\w+)/$'
weblog.views.tag'
新的:
archive_index'
archive_month'
urlpatterns+=patterns('
weblog.views'
tag'
整个框架关注的是存在一个名为urlpatterns的模块级别的变量。
这个变量可以动态构建,正如本例中我们所做的一样。
调试模式中的特例
当谈到动态构建urlpatterns时,你可能想利用这一技术,在Django的调试模式时,来修改URLconf的行为。
为了做到这一点,只要在运行时检查DEBUG配置项的值即可,如:
fromdjango.conf.urls.defaultsimport*
fromdjango.confimportsettings
^$'
mysite.views.homepage'
ifsettings.DEBUG:
urlpatterns+=patterns('
^debuginfo$'
mysite.views.debug'
)
在这个例子中,URL/debuginfo/将只有在你的DEBUG配置项设为True时才有效。
使用命名组
到目前为止,在所有URLconf例子中,我们使用的很简单,即无命名正则表达式组,在我们想要捕获的URL部分上加上小括号,Django会将捕获的文本作为位置参数传递给视图函数。
在更高级的用法中,还可以使用命名正则表达式组来捕获URL,并且将其作为关键字参数传给视图。
关键字参数对比位置参数
一个Python函数可以使用关键字参数或位置参数来调用,在某些情况下,可以同时进行使用。
在关键字参数调用中,你要指定参数的名字和传入的值。
在位置参数调用中,你只需传入参数,不需要明确指明哪个参数与哪个值对应,它们的对应关系隐含在参数的顺序中。
例如,考虑这个简单的函数:
defsell(item,price,quantity):
print"
Selling%sunit(s)of%sat%s"
%(quantity,item,price)
为了使用位置参数来调用它,你要按照在函数定义中的顺序来指定参数。
sell('
Socks'
$2.50'
6)
为了使用关键字参数来调用它,你要指定参数名和值。
下面的语句是等价的:
sell(item='
price='
quantity=6)
quantity=6,price='
sell(price='
item='
quantity=6,item='
sell(quantity=6,item='
sell(quantity=6,price='
最后,你可以混合关键字和位置参数,只要所有的位置参数列在关键字参数之前。
下面的语句与前面的例子是等价:
在Python正则表达式中,命名的正则表达式组的语法是(?
P<
name>
pattern),这里name是组的名字,而pattern是匹配的某个模式。
下面是一个使用无名组的URLconf的例子:
^articles/(\d{4})/$'
views.year_archive),
^articles/(\d{4})/(\d{2})/$'
views.month_archive),
下面是相同的URLconf,使用命名组进行了重写:
^articles/(?
year>
\d{4})/$'
\d{4})/(?
month>
\d{2})/$'
这段代码和前面的功能完全一样,只有一个细微的差别:
把提取的值用命名参数的方式传递给视图函数,而不是用按顺序的匿名参数的方式。
例如,如果不带命名组,请求/articles/2006/03/将会等于这样的函数调用:
month_archive(request,'
2006'
03'
而带命名组,同样的请求就是这样的函数调用:
month_archive(request,year='
month='
使用命名组可以让你的URLconfs更加清晰,减少参数次序可能搞混的潜在BUG,还可以让你在函数定义中对参数重新排序。
接着上面这个例子,如果我们想修改URL把月份放到年份的前面,而不使用命名组的话,我们就不得不去修改视图month_archive的参数次序。
如果我们使用命名组的话,修改URL里提取参数的次序对视图没有影响。
当然,命名组的代价就是失去了简洁性:
一些开发者觉得命名组的语法丑陋和显得冗余。
命名组的另一个好处就是可读性强,特别是熟悉正则表达式或自己开发的Django应用的开发者。
看一眼URLconf里的这些命名组就知道这是干什么用的了。
理解匹配/分组算法
需要注意的是如果在URLconf中使用命名组,那么命名组和非命名组是不能同时存在于同一个URLconf的模式中的。
如果你这样做,Django不会抛出任何错误,但你可能会发现你的URL并没有像你预想的那样匹配正确。
具体地,以下是URLconf解释器有关正则表达式中命名组和非命名组所遵循的算法。
如果有任何命名的组,Django会忽略非命名组而直接使用命名组。
否则,Django会把所有非命名组以位置参数的形式传递。
在以上的两种情况,Django同时会以关键字参数的方式传递一些额外参数。
更具体的信息可参考下一节。
传递额外的参数到视图函数中
有时你会发现你写的视图函数是十分类似的,只有一点点的不同。
比如说,你有两个视图,它们的内容是一致的,除了它们所用的模板不太一样:
#urls.py
^foo/$'
views.foo_view),
^bar/$'
views.bar_view),
#views.py
fromdjango.shortcutsimportrender_to_response
frommysite.modelsimportMyModel
deffoo_view(request):
m_list=MyModel.objects.filter(is_new=True)
returnrender_to_response('
template1.html'
{'
m_list'
:
m_list})
defbar_view(request):
template2.html'
我们在这代码里面做了重复的工作,不够简练。
起初你可能会想,通过对两个URL都试用同样的视图,在URL中使用括号捕捉请求,然后在视图中检查并决定使用哪个模板来去除代码的冗余,就像这样:
^(foo)/$'
views.foobar_view),
^(bar)/$'
deffoobar_view(request,url):
ifurl=='
foo'
template_name='
elifurl=='
bar'
returnrender_to_response(template_name,{'
这种解决方案的问题还是老缺点,就是把你的URL耦合进你的代码里面了。
如果你打算把/foo/改成/fooey/的话,那么你就得记住要去改变视图里面的代码。
优雅的解决方法:
使用一个额外的URLconf参数。
一个URLconf里面的每一个模式可以包含第三个数据:
一个传到视图函数中的关键字参数的字典。
有了这个概念以后,我们就可以把我们现在的例子改写成这样:
views.foobar_view,{'
template_name'
'
}),
deffoobar_view(request,template_name):
如你所见,这个例子中,URLconf指定了template_name。
而视图函数则会把它处理成另一个参数而已。
这额外的URLconf参数的技术以最少的麻烦给你提供了向视图函数传递额外信息的一个好方法。
正因如此,这技术已被很多Django的捆绑应用使用,其中以我们将会在第9章讨论的通用视图系统最为明显。
下面的几节里面有一些关于你可以怎样把额外URLconf参数技术应用到你自己的工程的建议。
伪造捕捉到的URLconf值
比如说你有匹配某个模式的一堆视图,以及一个并不匹配这个模式的但它的视图逻辑是一样的URL。
这种情况下,你可以伪造URL值的捕捉。
这主要通过使用额外URLconf参数,使得这个多出来的URL使用同一个视图。
例如,你可能有一个显示某一个特定日子的某些数据的应用,URL类似这样的:
/mydata/jan/01/
/mydata/jan/02/
/mydata/jan/03/
#...
/mydata/dec/30/
/mydata/dec/31/
这太简单了,你可以在一个URLconf中捕捉这些值,像这样(使用命名组的方法):
^mydata/(?
\w{3})/(?
day>
\d\d)/$'
views.my_view),
然后视图函数的原型看起来会是:
defmy_view(request,month,day):
#....
这种解决方案很直接,没有用到什么你没见过的技术。
问题在于当你想为添加一个使用my_view视图的URL但它没有包含一个month和/或者一个day。
比如你可能会想增加这样一个URL,/mydata/birthday/,这个URL等价于/mydata/jan/06/。
这时你可以这样利用额外URLconf参数:
^mydata/birthday/$'
views.my_view,{'
month'
jan'
day'
06'
在这里最帅的地方莫过于你根本不用改变你的视图函数。
视图函数只会关心它获得了month和day参数,它不会去管这些参数到底是捕捉回来的还是被额外提供的。
创建一个通用视图
抽取出我们代码中共性的东西是一个很好的编程习惯。
比如,像以下的两个Python函数:
defsay_hello(person_name):
print'
Hello,%s'
%person_name
defsay_goodbye(person_name):
Goodbye,%s'
我们可以把问候语提取出来变成一个参数:
defgreet(person_name,greeting):
%s,%s'
%(greeting,person_name)
通过使用额外的URLconf参数,你可以把同样的思想应用到Django的视图中。
了解这个以后,你可以开始创作高抽象的视图。
更具体地说,比如这个视图显示一系列的Event对象,那个视图显示一系列的BlogEntry对象,并意识到它们都是一个用来显示一系列对象的视图的特例,而对象的类型其实就是一个变量。
以这段代码作为例子:
^events/$'
views.event_list),
^blog/entries/$'
views.entry_list),
frommysite.modelsimportEvent,BlogEntry
defevent_list(request):
obj_list=Event.objects.all()
mysite/event_list.html'
event_list'
obj_list})
defentry_list(request):
obj_list=Blo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第八章 高级视图和URL配置 第八 高级 视图 URL 配置