Фильтр Джанго, если поле не None - PullRequest
1 голос
/ 19 мая 2019

У меня есть модель, где я могу установить expire_date. Я хочу отфильтровать модель, и когда есть набор expire_date, он должен фильтровать, если expire_date ниже, чем сейчас.

Я пытался сделать это с помощью Case и When, но я не могу отфильтровать функцию When, могу ли я?

News.objects.all().annotate(is_expired=Case(When(F("expire_date") != None, then=False if F("expire_date") <= datetime.now() else True))).filter(is_expired=False)

1 Ответ

1 голос
/ 19 мая 2019

Вы можете, condition должен быть Q объектом, или вы указываете условие через именованные параметры:

from django.db.models import BooleanField, Case, Q, When

News.objects.annotate(
    is_expired=Case(
        When(
            <b>condition=Q(expire_date__isnull=True) | Q(expire_date__gte=datetime.now())</b>,
            then=True
        ),
        default=False,
        output_field=BooleanField()
    )
).filter(is_expired=False)

Вы не можете писать код Python с троичными операторами и т. Д., А затем надеяться, что он автоматически преобразуется в запрос SQL.

Как говорится, здесь вы просто фильтруете аннотацию, так что вы можете просто написать это как:

News.objects.filter(<b>Q(expire_date__isnull=True) | Q(expire_date__gte=datetime.now())</b>)

это, таким образом, будет включать все New s объекты с expire_date, равным NULL, или где expire_date больше или равно datetime.now(). Логика в вашем ответе не имела особого смысла, так как она аннотировала бы is_expired со всеми ненулевыми expire_date с нулями или где expre_date на меньше , чем текущее время.

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