29

我想在 Django 中的模型的几个字段中查找某个字符串。理想情况下,它会类似于:

keyword = 'keyword'
fields = ['foo', 'bar', 'baz']
results = []
for field in fields:
    lookup = "%s__contains"
    results.append(Item.objects.filter(lookup=keyword))

当然这行不通,因为“查找”无法解析为字段。有没有其他方法可以做到这一点?

4

3 回答 3

47

我更愿意将 Q 对象用于这样的事情。

from django.db.models import Q

keyword = 'keyword'
fields = ['foo', 'bar', 'baz']

Qr = None
for field in fields:
    q = Q(**{"%s__contains" % field: keyword })
    if Qr:
        Qr = Qr | q # or & for filtering
    else:
        Qr = q

# this you can now combine with other filters, exclude etc.    
results = MyModel.objects.filter(Qr)
于 2009-08-06T15:15:20.267 回答
33

我认为使用 Django 查询系统可能有更好的方法来做到这一点。以下是如何按照您的方式进行操作。

Python 允许您通过在字典前面加上 ** 来传递用作参数列表的字典。运气好的话,您应该能够执行以下操作:

lookup = "%s__contains" % field
results.append(Item.objects.filter(**{ lookup: keyword}))
于 2009-08-04T12:15:30.063 回答
7

我喜欢 DialZ 的回答,但出于性能原因,您应该构建查询,然后访问数据库一次,而不是将所有结果连接到列表中:

keyword = 'keyword'
fields = ['foo', 'bar', 'baz']

# this makes an empty queryset object which we can
# add to later using the | operator
results = Item.objects.none()

for field in fields:
    lookup = "%s__contains" % field
    query = {lookup : keyword}
    results = results | Item.objects.filter(**query)

我已经有一段时间没有做过这些了,但我很确定 django 在这段代码中根本不会真正访问数据库。它只会在您访问记录中包含的数据时执行查询

于 2009-08-04T17:27:46.177 回答