整理复杂的URL调度程序

时间:2009-09-23 23:56:19

标签: django django-urls

我想在同一个网址下生活两种不同的对象。需要将一组对象传递给视图函数'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的方法的任何建议都将非常感激。

4 个答案:

答案 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替换为捕获所有网址的网址,然后移动逻辑以在视图中选择foobar网址。

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配置设置。