【问题标题】:Django, query_set annotation with conditional expressionDjango,使用条件表达式进行查询集注释
【发布时间】:2015-07-11 19:01:16
【问题描述】:

我有一个模型:

class Document(models.Model):
    expiry_date = models.DateField()

我如何构建一个查询来获取所有文档并给它们注释是否过期日期已过? 我试过这个:

today = timezone.now.date()

Document.objects.annotate(
    expired=Value(
        F('expiry_date')<today, 
        BooleanField()
    )
)

但它会引发错误:TypeError: unorderable types: F() &lt; datetime.date() 如何将 F() 表达式中的值与日期进行比较?

另外,我想避免使用 SQL 和 .extra()

【问题讨论】:

    标签: django django-queryset


    【解决方案1】:

    没有必要在数据库中这样做。将其放入模型方法中:

    class Document(models.Model):
        expiry_date = models.DateField()
    
        def expired(self):
            return self.expiry_date < timezone.now.date()
    

    【讨论】:

    • 不应该是self.expiry_date
    • 我需要在查询集中进行,因为稍后我希望能够调用.order_by('expired')
    【解决方案2】:

    您可以使用条件注释。

    Django 1.11.10测试。

    from django.db.models import BooleanField, Case, When  
    from django.utils import timezone
    
    Document.objects.annotate(
        expired=Case(
            When(expiry_date__lt=timezone.now(), then=True),
            default=False,
            output_field=BooleanField()
        )
    ).order_by('expired')
    

    【讨论】:

      【解决方案3】:

      这适用于 Django >= 2,不检查以前的版本

      from django.db import models
      from django.db.models import ExpressionWrapper, Q
      from django.db.models.functions import Now
      
      Document.objects.annotate(
          expired=ExpressionWrapper(Q(expiry_date__lt=Now()),
          output_field=models.BooleanField())
      )
      

      来源: https://stackoverflow.com/a/57114224/11193405

      【讨论】:

        猜你喜欢
        • 2019-12-30
        • 1970-01-01
        • 2018-07-24
        • 1970-01-01
        • 1970-01-01
        • 2018-05-29
        • 2019-04-03
        • 1970-01-01
        • 2023-03-27
        相关资源
        最近更新 更多