Как динамически объединить несколько параметров для объекта Q django

Я пытаюсь реализовать поиск в django sqlite db.

Я получаю список параметров неизвестной длины, которые должны соответствовать "LIKE". Это означает, что я хочу, чтобы все объекты соответствовали хотя бы одному из параметров.

Как я могу видеть из документации Django, я могу достичь этого, используя объект Q.

Пример:

Students.objects.get(
    Q(name_contains='franz') | 
    Q(birthdate_date=date(2005, 5, 2) | 
    Q(param3_contains='lorem'
)

Теперь мой вопрос: как я могу обработать это, чтобы объединить все объекты Q, созданные из params, для передачи в качестве аргументов objects.get(). Я не мог найти по этому вопросу.

Другой проблемой здесь является обработка нескольких различных типов поиска полей.

Я ценю любые советы, помощь или помощь ссылки, которые вы можете дать. Спасибо.

2 ответа

Решение

Если вы хотите динамически построить список запросов, вы можете иметь следующую последовательность:

request = Q(name_contains='franz')

if condition1:
  request |= Q(birthdate_date=date(2005, 5, 2))

if condition2:
  request |= Q(param3_contains='lorem')

Затем:

Students.objects.get(request)

Если вам нужно что-то еще более общее, у вас может быть функция, которая передает dict, например:

conditions = {'name_contains': 'franz',
              'birthdate_date': date(2005, 5, 2),
              'param3_contains': 'lorem'}

И создайте условие следующим образом (не проверено):

request = None
for key, value in conditions:
  new_request = Q(**{key: value})

  if request: request |= new_request
  else: request = new_request

У меня есть подобное требование в моем приложении. Я должен искать searchterm во всех видах имен:

Qterm = Q(firstname__icontains=searchterm) | \
        Q(lastname__icontains=searchterm) | \
        Q(resume__icontains=searchterm) | \
        Q(companyname__icontains=searchterm))

или, если вы хотите сопоставить одно поле с количеством поисковых терминов:

Qterm = Q()
for term in ["robot", "animatronic", "automaton"]:
    Qterm |= Q(rolename_icontains=term)

fieldname_icontains в конечном итоге становится LIKE, Есть и другие критерии, например, что пользователь должен быть "активным", что является логическим полем:

Qactive = Q(active=True)

В конце я объединяю все эти объекты Q следующим образом:

Qs = Qterm & Qactive & Qthis & Qthat 

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

userlst = Users.objects.filter(Qs)

Надеюсь, это поможет!

Другие вопросы по тегам