代码之家  ›  专栏  ›  技术社区  ›  Daniel Naab

django:任意数量的未命名URL.py参数

  •  18
  • Daniel Naab  · 技术社区  · 16 年前

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

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

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

    现在,这可以用get参数来处理,但是为了用户和搜索引擎,我更喜欢更可读的URL。这些URL子集将嵌入到显示此模型的每个页面中,因此似乎值得努力创建漂亮的URL。

    理想情况下,每个名称/值对都将作为名为 name1 , name2 等等。但是,我不认为通过regex的匹配文本来定义命名模式是可能的。我错了吗?

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

    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的regex支持的限制吗?这两种方法似乎都能奏效。有没有一种方法可以在不将URL中的每个可能的模型属性硬编码为可选(.%)模式的情况下实现这一点?

    5 回复  |  直到 9 年前
        1
  •  14
  •   Adam    16 年前

    您可能会考虑在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
        ...
    

    关于我使用的regexp没有承诺,但我想你明白我的意思。

    (编辑以尝试修复regexp。)

        2
  •  3
  •   Peter Rowell    16 年前

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

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

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

        3
  •  0
  •   Valera Grishin    16 年前

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

    我认为模型浏览视图是对查询参数进行排序并将其用作通用路由器的最佳方法。

        4
  •  0
  •   Michael    11 年前

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

    下面的示例显示如何通过输入一个地点的名称来获取一天的所有销售额。 store 以及 year , month day .

    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]+) . 注意 location sales 不是关键字,它们只是提高了URL的可读性。

    VIEW

    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
  •  0
  •   softwareplay    9 年前

    我有另一种解决方案,与以前的方案没有太大的不同,但它更精致:

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

    我已经用过 unnamed url parameters 以及重复的regexp。不获取“不是有效的正则表达式:多次重复”我将一个词放在列表的开头。

    我还在视图中接收列表。但我想我会通过禁运或禁运。还是说不清楚。

    我的2分钱