Django somehow cannot determine simple annotate function

与世无争的帅哥 提交于 2021-01-01 08:20:14

问题


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?

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.


回答1:


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()
  )
)


来源:https://stackoverflow.com/questions/48488703/django-somehow-cannot-determine-simple-annotate-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!