因此,我有了这个 Django 应用程序,并且我不断添加新功能以提供更精细的数据 View 。为了快速了解问题,这里是 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'),
所以,是的,默认 View 、日期 View 、分页 View ,然后是针对用户特定 URL 的类似设置:
# 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'),
然后,Teams 再次类似。 . .
# 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'),
现在,我想添加一个“搜索” View ,我真的认为将其添加到上述许多 URL 的末尾会很好,这样我就可以点击:
/search/foo
/user/fred/date/2010-01/search/baz
然后我可以将搜索参数传递给 View ,这可以适本地限制结果。
但是,如果我想将其应用到用户、团队和按日期 View ,我已将 12 行新行添加到 urls.py。每次我添加另一个潜在的 View 选项(比如,分页搜索结果?)。 . .感觉应该有更好的方法。
根据我的研究,答案似乎是:
1) 在 urls.py 中进行更广泛的匹配,并让 View 函数解析查询字符串。
2) urls.py 中可能有一些更强大的正则表达式逻辑,可以多次说“如果此模式匹配,则在传递给 View 函数时包含参数”。但这可能是噩梦般的维持。
有没有人想出一个更明智的解决方案来优雅地管理复杂的 URL?我在想,在某个时候,最简单的方法是将参数匹配逻辑传递给 View 本身,从查询字符串中解析参数。因此,在 View 顶部附近,我可能有一些代码如下所示:
# 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 中引入的减少重复复杂性的巧妙方法吗?
请您参考如下方法:
为什么不使用 GET 参数,或者 django-filter ,如果您所做的只是对结果进行不同的过滤/分组?
我看到使用 GET 的原因是它更容易实现,而且看起来更简洁:在 URL 解决方案中/search/foo/user/bar/和/user/bar/search/foo/是 2 个名称完全相同的内容。在 GET 参数解决方案中,所有页面都是相同的。
