在Django中,如何使用dynamic字段查找过滤QuerySet?
给定一个类:
from django.db import models class Person(models.Model): name = models.CharField(max_length=20)
是否有可能,如果是这样,有一个基于dynamic参数的filter的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调查应用程序中,我想要一个显示注册用户的HTMLselect列表。 但是因为我们有5000个注册用户,所以我需要根据查询条件(比如只是完成某个工作坊的人)过滤这个列表。 为了使调查元素可重复使用,我需要创build调查问题的人员能够将这些标准附加到该问题(不想将查询硬编码到应用程序中)。
我提出的解决scheme不是100%的用户友好(需要技术人员的帮助来创build查询),但它确实解决了这个问题。 在创build问题时,编辑器可以将字典input到自定义字段中,例如:
{'is_staff':True,'last_name__startswith':'A',}
该string存储在数据库中。 在视图代码中,它以self.question.custom_query
。 那个值是一个看起来像字典的string。 我们用eval()把它变成一个真正的字典,然后用** kwargs把它填入查询集:
kwargs = eval(self.question.custom_query) user_list = User.objects.filter(**kwargs).order_by("last_name")
Django.db.models.Q正是你想用Django的方式。
一个非常复杂的search表单通常表明,一个更简单的模型正试图挖掘出来的方式。
你到底希望得到列名和操作的值? 你在哪里得到'name'
和'startswith'
?
filter_by = '%s__%s' % ('name', 'startswith')
-
一个“search”forms? 你会 – 什么? – 从名单中select名字? 从操作列表中select操作? 虽然是开放式的,但是大多数人都觉得这种混乱和难以使用。
有多less列有这样的filter? 6? 12? 18?
- 一些? 一个复杂的select列表是没有意义的。 几个领域和一些if语句是有道理的。
- 大量? 你的模型听起来不对。 这听起来像“字段”实际上是另一个表中的行的关键,而不是一列。
-
特定的过滤button。 等等…这就是Djangopipe理员工作的方式。 特定的filter被转换成button。 和上面相同的分析也适用。 一些filter是有道理的。 大量的filter通常意味着一种第一范式违规。
许多类似的字段通常意味着应该有更多的行和更less的字段。