【问题标题】:Filtering QuerySet based on captured URL parameters in Django?根据Django中捕获的URL参数过滤QuerySet?
【发布时间】:2012-04-22 06:29:27
【问题描述】:

我正在制作一个通用模板,它将显示来自查询集的对象列表:

{% for o in objects %}
    {{ o.name }}
{% endfor %}

我希望能够在需要进行不同类型的过滤和排序的多种情况下使用该模板。我为此创建了一个视图函数:

def display_objects(request, filters, orders, template_name):
    objects = Object.objects.all()
    for filter in filters:
        objects = objects.filter(('%s__%s' % (filter['field'], filter['relationship']), filter['value']))
    for order in orders:
        objects = objects.order_by('-' if 'descending' in order else '' + order['field'])
    # render objects to template with context
    pass

我不确定到目前为止我所做的是否会奏效,但我遇到了一个问题。我不知道用我当前的函数过滤URL中捕获的参数设置的查询是否可行。

例如,如果我想显示属于某个用户的对象,我会执行以下操作:

(r'^user/(?P<account_username>[^/]+)/$', display_objects, dict(filters=[{'field':'account__username','relationship':'iexact','value':account_username}], orders=[{'field':'foobar'}], template_name='user.html'))

显然,在 URL 被解析并分派给 display_objects 函数之前,account_username 不是一个已定义的字段。制作一个带有 account_username 参数的视图函数很容易,但我希望能够使用该函数来显示其他对象查询集,这些对象查询集将使用不同的捕获参数进行过滤。

有什么方法可以将捕获的 URL 参数传递给视图函数以动态过滤或排序要显示的查询集?

【问题讨论】:

    标签: python django django-urls


    【解决方案1】:

    这是您可以做到这一点的一种方法:

    在 urls.py 中:

    (r'^user/(?P<account_username>[^/]+)/$', display_objects, dict(filters=[{'field':'account__username','relationship':'iexact'}], orders=[{'field':'foobar'}], template_name='user.html'))
    

    然后在views.py中:

    def display_objects(request, filters, orders, template_name, **kwargs):
    
        objects = Object.objects.all()
        for filter in filters:
            objects = objects.filter(('%s__%s' % (filter['field'], filter['relationship']), kwargs.get(filter['field'])))
        for order in orders:
            objects = objects.order_by('-' if 'descending' in order else '' + order['field'])
        # render objects to template with context
        pass
    

    虽然老实说我不确定这是否是一种很好的做事方式......

    【讨论】:

    • 当我思考时,我意识到我构建视图函数的方式可能不是最佳的。对于如何为模板动态过滤和排序查询集,您有什么建议吗?
    【解决方案2】:

    您不能将字符串直接传递给filter 方法。你需要把它翻译成kwargs。

    query_string = '%s__%s' % (filter['field'], filter['relationship'])
    objects = objects.filter(**{query_string: filter['value']}))
    

    【讨论】:

    • 我不确定这是什么时候发生的,但他的语法适用于 1.4A obj.filter(('key', 'value'))。也让我措手不及,但它接受键/值元组。 !?
    猜你喜欢
    • 1970-01-01
    • 2021-11-24
    • 2016-03-22
    • 2023-03-30
    • 2014-07-13
    • 1970-01-01
    • 2021-06-16
    • 2018-06-04
    • 2018-01-05
    相关资源
    最近更新 更多