如果字段不是无,则Django过滤器

Myz*_*394 4 python 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)
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 6

你可以,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)
Run Code Online (Sandbox Code Playgroud)

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

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

News.objects.filter(Q(expire_date__isnull=True) | Q(expire_date__gte=datetime.now()))
Run Code Online (Sandbox Code Playgroud)

因此,这将包括所有New具有expire_date等于NULL或其中expire_date大于或等于 的对象datetime.now()。在你的答案的逻辑并没有太大的意义,因为这将注释is_expired与所有非空expire_dateS中的空,或者expre_date比当前时间。