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

Я пытаюсь запросить базу данных на основе тегов пользовательского ввода. Количество тегов может быть от 0-5, поэтому мне нужно создать запрос динамически.

Итак, у меня есть список тегов, tag_list, и я хочу запросить базу данных:

design_list = Design.objects.filter(Q(tags__tag__contains = "tag1") and Q(tags__tag__contains = "tag2") and etc. etc. )

Как я могу создать эту функцию?

3 ответов


вы хотите, чтобы цикл через tag_list и примените фильтр для каждого из них.

tag_list = ['tag1', 'tag2', 'tag3']
base_qs = Design.objects.all()
for t in tag_list:
    base_qs = base_qs.filter(tags__tag__contains=t)

это даст вам результаты, соответствующие все теги, как указано в вашем примере с and. Если на самом деле вам нужно or вместо этого вам, вероятно, понадобятся Q объектов.

Edit: я думаю, что у меня есть то, что вы ищете сейчас.

tags = ['tag1', 'tag2', 'tag3']
q_objects = Q() # Create an empty Q object to start with
for t in tags:
    q_objects |= Q(tags__tag__contains=t) # 'or' the Q objects together

designs = Design.objects.filter(q_objects)

Я проверил это, и это, кажется, работает очень хорошо.

Edit 2: кредит кезабель в #django на Freenode для первоначальной идеи.


Сначала подготовьте список тегов, затем выполните запрос следующим образом:

tags = ['tag1', 'tag2',...]
design_list = Design.objects.filter(tags__tag__contains__in = tags)

вы можете использовать таким образом:

my_dict = {'field_1': 1, 'field_2': 2, 'field_3': 3, ...}  # Your dict with fields
or_condition = Q()
for key, value in my_dict.items():
    or_condition.add(Q(**{key: value}), Q.OR)

query_set = MyModel.objects.filter(or_condition)

таким образом, вы можете использовать динамически генерируемые имена полей. Также вы можете использовать Q.AND на AND состояние.