首页 > 解决方案 > 如果字段不是无,则 Django 过滤器

问题描述

我有一个可以设置的模型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)

标签: pythondjango

解决方案


您可以,condition应该是一个Q对象,或者您通过命名参数指定条件:

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

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

你不能用三元运算符等编写 Python 代码,然后希望它自动转换为 SQL 查询。

话虽如此,在这里您只需过滤注释,因此您可以将其写为:

News.objects.filter(Q(expire_date__isnull=True) | Q(expire_date__gte=datetime.now()))

因此,这将包括所有等于或大于或等于New的 s 对象。您的答案中的逻辑没有多大意义,因为它会用所有为 null 或 where小于当前时间非 null s 进行注释。expire_dateNULLexpire_datedatetime.now()is_expiredexpire_dateexpre_date


推荐阅读