Django:任意数量的未命名 urls.py 参数

Posted

技术标签:

【中文标题】Django:任意数量的未命名 urls.py 参数【英文标题】:Django: Arbitrary number of unnamed urls.py parameters 【发布时间】:2010-09-19 22:21:09 【问题描述】:

我有一个包含大量字段和 20000 多个表行的 Django 模型。为了促进人类可读的 URL 和将大列表分解为任意子列表的能力,我希望有一个如下所示的 URL:

/browse/<name1>/<value1>/<name2>/<value2>/ .... etc ....

其中“名称”映射到模型属性,“值”是该属性的搜索条件。每个“名称”都将被视为一个类别,以返回类别匹配的模型实例的子集。

现在,这可以使用 GET 参数来处理,但为了用户和搜索引擎,我更喜欢可读性更高的 URL。这些 URL 子集将嵌入显示此模型的每个页面上,因此制作漂亮的 URL 似乎值得。

理想情况下,每个名称/值对都将作为名为@9​​87654322@、name2 等的参数传递给视图函数。但是,我不相信可以通过正则表达式的匹配文本来定义命名模式。我错了吗?

所以,看来我需要做这样的事情:

urlpatterns = patterns('',
    url(r'^browse/(?:([\w]+)/([\w]+)/)+$', 'app.views.view', name="model_browse"),
)

似乎这应该匹配任何两个名称/值对的集合。虽然匹配成功,但它只将最后一个名称/值对作为参数传递给视图函数。我的猜测是每场比赛都会覆盖前一场比赛。根据包含 (?:...)+ 的猜测,我尝试了一个简单的重复模式:

urlpatterns = patterns('',
    url(r'^browse/([\w]+/)+$', 'app.views.view', name="model_browse"),
)

...遇到了同样的问题,但这次*args 只包含最后匹配的模式。

这是 Django 的 url 调度程序和/或 Python 的正则表达式支持的限制吗?似乎这些方法中的任何一种都应该有效。有没有办法在不将 URL 中每个可能的模型属性硬编码为可选 (.*) 模式的情况下实现这一点?

【问题讨论】:

我认为使用 url 本身实现“GET query like”键值参数有点丑陋而不是“真实”。 @alex - 除了网址不可读之外,如果您有多个 get 参数(如果有的话),搜索引擎可能不会索引您的所有内容。 【参考方案1】:

您可能考虑的一种可能性是匹配 url 模式部分中的整个可能值字符串,并在您的视图中提取特定部分。举个例子:

urlpatterns = patterns('',
    url(r'^browse/(?P<match>.+)/$', 'app.views.view', name='model_browse'),
)

def view(request, match):
    pieces = match.split('/')
    # even indexed pieces are the names, odd are values
    ...

对我使用的正则表达式没有任何承诺,但我想你明白我的意思。

(已编辑以尝试修复正则表达式。)

【讨论】:

谢谢,我同意这可能是解决问题的最简单方法。 只是为了在我的情况下为其他人提供一些文本,这是我找到的用于解析matrix URI 中任意数量的矩阵元素的唯一解决方案。将所有矩阵元素匹配在一起,然后在视图中解析。 这里也是,现在是 2016 年【参考方案2】:

我同意 Adam,但我认为 urls.py 中的模式应该是:

... r'^browse/(?P<match>.+)/$' ...

'\w' 只会匹配 'word' 字符,但 '.'将匹配任何东西。

【讨论】:

我不擅长正则表达式,只是猜测,呵呵。【参考方案3】:

阅读问题时,我得到了同样的答案。

我相信 model_browse 视图是对查询参数进行排序并将其用作通用路由器的最佳方式。

【讨论】:

【参考方案4】:

我认为 Adam 的答案比我的解决方案更通用,但如果你想在 url 中使用固定数量的参数,你也可以这样做:

以下示例显示如何通过输入 storeyearmonthday 的名称来获取某个位置一天的所有销售额。

urls.py

urlpatterns = patterns('',
    url(r'^baseurl/location/(?P<store>.+)/sales/(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9])-(?P<day>[0-9][0-9])/$', views.DailySalesAtLocationListAPIView.as_view(), name='daily-sales-at-location'),
)

另外,您还可以通过将(?P&lt;store&gt;.+) 更改为(?P&lt;store&gt;[0-9]+) 来使用商店的ID。注意locationsales不是关键字,它们只是提高url的可读性。

views.py

class DailySalesAtLocationListAPIView(generics.ListAPIView):
    def get(self, request, store, year, month, day):
        # here you can start using the values from the url
        print store
        print year
        print month
        print date

        # now start filtering your model

希望对大家有帮助!

最好的问候,

迈克尔

【讨论】:

【参考方案5】:

我有一个替代解决方案,它与以前的解决方案没有太大区别,但更精致:

url(r'^my_app/(((list\/)((\w1,)\/(\w1,)\/(\w1,3)\/)1,10)+)$'

我使用了unnamed url parameters 和一个重复的正则表达式。为了不得到“不是有效的正则表达式:多次重复”,我在列表的开头放置了一个单词。

我仍在处理接收列表的视图。但我认为我会通过 args 或 kwargs.. 仍然不能准确地说出来。

我的 2 美分

【讨论】:

以上是关于Django:任意数量的未命名 urls.py 参数的主要内容,如果未能解决你的问题,请参考以下文章

Django 路由 urls.py

Django 忽略对 urls.py 的更新

Django:使用任意 URL 组件进行反向 URL 查找

二 Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器

你如何使用 Django URL 命名空间?

python - django (路由)