我想在同一个网址下生活两种不同的对象。需要将一组对象传递给视图函数'foo',另一组需要传递给'bar'。
我目前正在使用大量的硬编码网址,例如......
urlpatterns = patterns('project.views',
(r'^a/$', 'foo'),
(r'^b/$', 'foo'),
(r'^c/$', 'foo'),
#...and so on until...
(r'^x/$', 'bar'),
(r'^y/$', 'bar'),
(r'^z/$', 'bar'),
)
是否可以定义每种类型的URL的列表,如...
foo_urls = ['a', 'b', 'c'] #...
bar_urls = ['x', 'y', 'z'] #...
...然后根据这些列表检查传入的URL? (如果它在'foo_urls'中,发送到'project.views.foo';如果它在'bar_urls'中,发送到'project.views.bar')?
我仅限于保持此结构以保持与之前网站的网址的兼容性,但是对于简化我的urls.py的方法的任何建议都将非常感激。
答案 0 :(得分:5)
网址映射通常是明确表达的,但并非必须如此。如何从列表中构建您的URL地图?
foo_urls = ['a', 'b', 'c'] #...
bar_urls = ['x', 'y', 'z'] #...
# A first pattern to get urlpatterns started.
urlpatterns = pattern('project.views',
('blah', 'blah')
)
# Append all the foo urls.
for foo_url in foo_urls:
urlpatterns += patterns('project.views',
('^' + foo_url + '/$', 'foo')
)
# Append all the bar urls.
for bar_url in bar_urls:
urlpatterns += patterns('project.views',
('^' + bar_url + '/$', 'bar')
)
答案 1 :(得分:4)
Django的url模式是正则表达式,所以这确实是可能的:
urlpatterns = patterns('project.views',
(r'^[abc]/$', 'foo'),
(r'^[xyz]/$', 'bar'),
)
如果您使用a,b,c作为非单字符的示例占位符,则可以使用完整字符串,但要小心确保它们遵循正则表达式匹配规则:
urlpatterns = patterns('project.views',
(r'^(foo|slithy|toves)/$', 'foo'),
(r'^(bar|twas|brillig)/$', 'bar'),
)
答案 2 :(得分:3)
您可以将urlpatterns替换为捕获所有网址的网址,然后移动逻辑以在视图中选择foo
和bar
网址。
urlpatterns = patterns('project.views',
(r'^(?P<letter>[a-z])/$', 'foobar'),
)
然后在foobar
views.py
def foobar(request, letter):
foo_urls = ['a', 'b', 'c'] #...
bar_urls = ['x', 'y', 'z'] #...
if slug in foo_urls:
return foo(request)
if slug in bar_urls:
return bar(request)
else:
#oh dear, you've caught a
#url that isn't foo or bar
#return 404?
作为替代方案,您可能想要探索django redirects app,重新设计网址结构,然后为旧网址设置重定向。
答案 3 :(得分:1)
如果你的应用程序前面有Apache:
<LocationMatch "^[a-w]/$">
...
</LocationMatch>
<LocationMatch "^[x-z]/$">
...
</LocationMatch>
...可以是您需要的任何配置指令,包括SetEnv,如果您想要一个环境变量来告诉您是否要转到foo vs bar,或者可能是ProxyPass将请求发送到几个不同的后端服务器网址。
您还可以使用url重写或许多其他接受正则表达式参数的Apache配置设置。