Как динамически указывать имя поля поиска в запросе Django?[дубликат]

StackOverflow https://stackoverflow.com/questions/1227091

  •  22-07-2019
  •  | 
  •  

Вопрос

На этот вопрос уже есть ответ здесь:

Я хочу найти определенную строку в нескольких полях модели в Django.В идеале это было бы примерно так:

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

Конечно, это не сработает, поскольку «поиск» нельзя преобразовать в поле.Есть ли другой способ сделать это?

Это было полезно?

Решение

Я думаю, что есть лучший способ сделать это с помощью системы запросов Django.Вот как это сделать по-вашему.

Python позволяет передавать словари для использования в качестве списков аргументов, добавляя к ним префикс **.Если повезет, вы сможете сделать что-то вроде этого:

lookup = "%s__contains" % field
results.append(Item.objects.filter(**{ lookup: keyword}))

Другие советы

Я бы предпочел использовать объект 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)

Мне нравится ответ 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 вообще не обратится к базе данных.Он будет выполнять запрос только при доступе к данным, содержащимся в записях.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top