3

我有两种不同类型的对象,我希望它们存在于同一个 URL 下。一组对象需要传递给视图函数“foo”,另一组对象需要传递给“bar”。

我目前正在使用一长串硬编码的 URL 来执行此操作,就像这样......

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')?

我仅限于保留此结构以保持与上一个站点中的 URL 的兼容性,但任何有关简化我的 urls.py 的方法的建议将不胜感激。

4

4 回答 4

5

url 映射通常是明确表达的,但不一定非要如此。从您的列表中构建您的 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')
        )
于 2009-09-24T00:24:27.607 回答
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'),
)
于 2009-09-24T00:00:34.500 回答
3

您可以将 urlpatterns 替换为捕获所有 url 的模式,然后移动逻辑以在 url 和视图之间进行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重定向应用程序,重新设计 url 结构,然后为旧 url 设置重定向。

于 2009-09-24T00:28:36.340 回答
1

如果您的应用程序前面有 Apache:

<LocationMatch "^[a-w]/$">
   ...
</LocationMatch>

<LocationMatch "^[x-z]/$">
   ...
</LocationMatch>

... 可以是您需要的任何配置指令,包括 SetEnv,如果您想要一个环境变量来告诉您是否去 foo vs bar,或者可能是 ProxyPass 将请求发送到几个不同的后端服务器 url。

您还可以使用 url 重写或许多其他接受正则表达式参数的 Apache 配置设置。

于 2009-09-24T01:33:17.860 回答