Django无法确定简单的注释功能 [英] Django somehow cannot determine simple annotate function

查看:34
本文介绍了Django无法确定简单的注释功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在queryset类上创建一个批注,该批注仅添加一些标准查询结果的布尔值.

I'm trying to create an annotation on a queryset class that simply adds a boolean that is the result of some standard queries.

CustomQueryset(models.QuerySet):
    """ An extension of the traditional queryset to support
        filtering on accepting_offers """

    def annotate_with_accepting_offers(self):
        """ Add a lovely little variable to the SELECT that
            says if the listing is accepting offers.

            A <thing> is accepting offers when its:
                + not cancelled
                + expire date is today or in the future
                + has spaces left
        """
        return self.annotate(accepting_offers=Q(cancelled=False) & Q(expire_date__gte=date.today()) & Q(spaces_left__gt=0))

    def accepting_offers(self):
        """ Annotate with 'accepting_offers' and filter the results that are True """
        return self.annotate_with_accepting_offers().filter(accepting_offers=True)

    def not_accepting_offers(self):
        """ Annotate with 'accepting_offers' and filter the results that are False """
        return self.annotate_with_accepting_offers().filter(accepting_offers=False)

不幸的是,这行不通,有什么想法需要注释吗?

This unfortunately does not work, any ideas what annotation would?

如果这是SQL,则顶行应如下所示:

If this was SQL, the top line would look like:

SELECT *, (cancelled=False AND expire_date >= ? AND spaces_left > 0) AS accepting_offers


修改:我打算进行此批注的原因是为了简化对变量的过滤,您可以在接下来的两个后续函数中看到这一点.


Edit: The reasons I intend on making this annotation is to make filtering on the variable easier, which you can see in the next two proceeding functions.

这两个方法将在较大的查询链中使用,因此(具有讽刺意味的)通过注释使之保持简单应该会有所帮助.

These two methods would be used within a larger chain of queries, so (ironically) keeping it simple with an annotation should help.

推荐答案

正如我在评论中提到的,这根本不是Q表达式的全部.我认为您想要的是条件表达式:

As I mentioned in the comments, this isn't what Q expressions are for at all. I think what you want is a conditional expression:

return self.annotate(
  accepting_offers=Case(
    When(cancelled=False, expire_date__gte=date.today(), spaces_left__gt=0, then=Value(True)),
    default_value=Value(False),
    output_field=models.BooleanField()
  )
)

这篇关于Django无法确定简单的注释功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆