Активация/деактивация фильтрации в django на основе условия

У меня есть bool и если это True, то я хочу отфильтровать в запросе по некоторым параметрам, если нет, то я не хочу фильтровать.

На данный момент мое решение таково:

if my_boolean:
    objects = Class.objects.filter(argument=valuexyz)...
else:
    objects = Class.objects...

Мой реальный запрос намного длиннее. Я просто использовал это для упрощения. Теперь я хочу спросить, можно ли сделать это в строке?

Нравится: objects = Class.objects.filter( if my_boolean: argument=valuexyz; else: no_filtering)

Есть ли способ сделать это как-то иначе? Это позволило бы мне сэкономить несколько лишних строк кода.

Ваш текущий метод быстр и читабелен, учитывая, что есть только один булев и только 2 возможных запроса. Я бы оставил все как есть. Тем не менее, если ваш реальный сценарий использования более сложен, вы можете использовать:

  1. Распаковка аргумента ключевого слова с помощью оператора ** с оператором dict:
my_filter = {
  "field1": "foo"
  "field2__gt": 10
}
if my_boolean:
    my_filter["additional_field"] = "bar"
objects = MyModel.objects.filter(**my_filter)
  1. Q объекты:
my_q = Q(field1="foo", field2__gt=10)
if my_boolean:
    my_q &= Q(additional_field="bar")
objects = MyModel.objects.filter(my_q)

Вы можете работать с объектом Q, чтобы получить похожий синтаксис, например:

from django.db.models import Q

objects = Class.objects.filter(Q(('field__lookup', value) if condition else ()))

хотя, таким образом, она делает некоторую обертку. Возможно, лучший способ - сделать небольшую вспомогательную функцию:

def qif(*args, _if=True, **kwargs):
    if _condition:
        return Q(*args, **kwargs)
    return Q()

и использовать:

objects = Class.objects.filter(qif(field__lookup=value, _if=condition))

Note: It might be worth to take a look at django-filter [GitHub] to do filtering based on a QueryDict in a more declarative way.

Вернуться на верх