1

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

{% 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 参数传递给视图函数以动态过滤或订购要显示的查询集?

4

2 回答 2

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

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

于 2012-04-09T22:46:14.990 回答
0

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

query_string = '%s__%s' % (filter['field'], filter['relationship'])
objects = objects.filter(**{query_string: filter['value']}))
于 2012-04-09T23:04:39.480 回答