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

时间:2008-10-30 02:18:32

标签: python django django-urls

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

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

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

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

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

所以,似乎我需要做这样的事情:

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中的每个可能的模型属性硬编码为可选(。*)模式?

5 个答案:

答案 0 :(得分:14)

您可能考虑的可能性是匹配网址图案部分中的整个可能值字符串,并拉出视图中的特定部分。举个例子:

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
    ...

没有关于我使用的正则表达式的承诺,但我认为你理解我的意思。

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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

以下示例显示如何通过输入storeyearmonthday的名称来获取某个位置的所有销售。< / p>

<强> 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<store>.+)更改为(?P<store>[0-9]+)来使用商店的ID。请注意,locationsales不是关键字,只是提高了网址的可读性。

<强> 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

希望它可以帮助任何人!

致以最诚挚的问候,

迈克尔

答案 4 :(得分:0)

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

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

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

我仍在接收列表的视图中工作。但我认为生病了“通过args或kwargs ..仍然不能完全说出来。

我的2美分