所以,我有这个Django应用程序,我不断添加新功能,以提供更细粒度的数据视图。为了快速了解问题,这里是urls.py
的一个子集:
# Simple enough . . .
(r'^$', 'index'),
(r'^date/(?P<year>\d{4})$', 'index'),
(r'^date/(?P<year>\d{4})-(?P<month>\d{2})$', 'index'),
(r'^date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$', 'index'),
(r'^page/(?P<page>\d+)$', 'index'),
所以,是的,默认视图,日期视图,分页视图,然后是用户特定网址的类似设置:
# user
(r'^user/(?P<username>\w+)$', 'index_username'),
(r'^user/(?P<username>\w+)/date/(?P<year>\d{4})$', 'index_username'),
(r'^user/(?P<username>\w+)/date/(?P<year>\d{4})-(?P<month>\d{2})$', 'index_username'),
(r'^user/(?P<username>\w+)/date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$', 'index_username'),
(r'^user/(?P<username>\w+)/page/(?P<page>\d+)$', 'index_username'),
然后,类似于团队。 。
# Team View
(r'^team/(?P<team>\w+)$', 'index'),
(r'^team/(?P<team>\w+)/date/(?P<year>\d{4})$', 'index'),
(r'^team/(?P<team>\w+)/date/(?P<year>\d{4})-(?P<month>\d{2})$', 'index'),
(r'^team/(?P<team>\w+)/date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$', 'index'),
(r'^team/(?P<team>\w+)/page/(?P<page>\d+)$', 'index'),
现在,我想添加一个“搜索”视图,而且我认为将它添加到上述许多URL的末尾会很好,所以我可以点击:
/search/foo
/user/fred/date/2010-01/search/baz
然后我可以将搜索参数传递给视图,这可能会适当地约束结果。
但是,如果我想将其应用于用户,团队和最新视图,我已经在urls.py
添加了12个新行。每次我添加另一个潜在的视图选项(比如分页搜索结果?)。 。 。它只是觉得应该有更好的方式。
从我的研究中,答案似乎是:
1)urls.py
内的更广泛匹配,并使视图函数解析查询字符串
2)也许urls.py
中的一些更强大的正则表达式逻辑可以说“如果这种模式匹配,则在传递给视图函数时包括参数”多次。但这可能是噩梦般的维持。
有没有人想出一个更优雅的解决方案来优雅地管理复杂的URL?我认为在某一点上,最简单的方法是将参数匹配逻辑传递给视图本身,以便从查询字符串中解析出参数。因此,在视图的顶部附近,我可能会有一些看起来像这样的代码:
# Date Queries
re_ymd = re.compile('date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})')
re_ym = re.compile('date/(?P<year>\d{4})-(?P<month>\d{2})')
re_y = re.compile('date/(?P<year>\d{4})')
if( re_ymd.search(qs) ):
year = re_ymd.search(qs).group('year')
month = re_ymd.search(qs).group('month')
day = re_ymd.search(qs).group('day')
elif( re_ym.search(qs) ):
year = re_ym.search(qs).group('year')
month = re_ym.search(qs).group('month')
elif( re_y.search(qs) ):
year = re_y.search(qs).group('year')
# Pagination queries
re_p = re.compile('page/(?P<page>\d+)')
if( re_p.search(qs) ):
page = re_p.search(qs).group('page')
# Search queries
re_s = re.compile('search/(?P<search>\w+)')
if( re_s.search(qs) ):
search = re_s.search(qs).group('search')
那么,这是否是一种降低我urls.py
引入的重复复杂性的聪明方法?
答案 0 :(得分:3)
为什么不使用GET参数或django-filter,如果您只是对结果进行过滤/分组不同?
我看到使用GET的原因是它更容易实现,并且看起来更清晰:在URL解决方案/ search / foo / user / bar /和/ user / bar / search / foo /中有2个名称完全相同的内容。在GET参数解决方案中它的所有相同的页面。
答案 1 :(得分:0)
让我们关注这一点:
# Simple enough . . .
(r'^$', 'index'),
(r'^date/(?P<year>\d{4})$', 'index'),
(r'^date/(?P<year>\d{4})-(?P<month>\d{2})$', 'index'),
(r'^date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$', 'index'),
(r'^page/(?P<page>\d+)$', 'index'),
我认为有一些:
def index(year=2010, month=2, day=2, page=0):
# whatever
那么,为什么不将你的正则表达式合二为一,例如
r'^date/(?P<year>\d{4})(-(?P<month>\d{2})(-(?P<day>\d{2}))?)?$
我还没试过,但我很确定这样的东西会起作用。
编辑:
虽然重写正则表达式可行,但请看看Ofri Raviv的答案,因为这可能是你在这里遇到了一些元问题。