在Django中,如何使用动态字段查找过滤QuerySet?

给定一个类:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=20)

是否有可能,如果是这样,有一个基于动态参数的过滤器的QuerySet? 例如:

 # Instead of:
 Person.objects.filter(name__startswith='B')
 # ... and:
 Person.objects.filter(name__endswith='B')

 # ... is there some way, given:
 filter_by = '{0}__{1}'.format('name', 'startswith')
 filter_value = 'B'

 # ... that you can run the equivalent of this?
 Person.objects.filter(filter_by=filter_value)
 # ... which will throw an exception, since `filter_by` is not
 # an attribute of `Person`.

Python的参数扩展可能被用来解决这个问题:

kwargs = {
    '{0}__{1}'.format('name', 'startswith'): 'A',
    '{0}__{1}'.format('name', 'endswith'): 'Z'
}

Person.objects.filter(**kwargs)

这是一个非常常见和有用的Python成语。


一个简单的例子:

在Django调查应用程序中,我想要一个显示注册用户的HTML选择列表。 但是,因为我们有5000个注册用户,所以我需要一种基于查询条件过滤该列表的方法(例如只是完成某个工作坊的人员)。 为了使调查元素可以重复使用,我需要创建调查问题的人员能够将这些标准附加到该问题(不想将查询硬编码到应用程序中)。

我提出的解决方案不是100%用户友好的(需要技术人员帮助创建查询),但它确实解决了问题。 在创建问题时,编辑器可以将字典输入到自定义字段中,例如:

{'is_staff':True,'last_name__startswith':'A',}

该字符串存储在数据库中。 在视图代码中,它以self.question.custom_query 。 它的值是一个看起来像字典的字符串。 我们用eval()将它变成真正的字典,然后用** kwargs将它填充到查询集中:

kwargs = eval(self.question.custom_query)
user_list = User.objects.filter(**kwargs).order_by("last_name")   

Django.db.models.Q正是你想要的Django方式。

链接地址: http://www.djcxy.com/p/38709.html

上一篇: In Django, how does one filter a QuerySet with dynamic field lookups?

下一篇: Django filter on any matching column