How to fix AttributeError: 'WhereNode' object has no attribute 'select_format', raised by Django annotate()?

Question:

There are many similar questions on SO, but this specific error message did not turn up in any of my searches:

AttributeError: 'WhereNode' object has no attribute 'select_format'

This was raised when trying to annotate() a Django queryset with the (boolean) result of a comparison, such as the gt lookup in the following simplified example:

Score.objects.annotate(positive=Q(value__gt=0))

The model looks like this:

class Score(models.Model):
    value = models.FloatField()
    ...

How to fix this?

Asked By: djvg

||

Answers:

This case can be fixed using the ExpressionWrapper()

Score.objects.annotate(
    positive=ExpressionWrapper(Q(value__gt=0), output_field=BooleanField()))

From the docs:

ExpressionWrapper is necessary when using arithmetic on F() expressions with different types …

The same apparently holds for Q objects, although I could not find any explicit reference in the docs.

Answered By: djvg

You can also get this error message if you are trying to filter a count annotation, and accidentally put the filter clause in the wrong place. e.g. if you’re following this example but instead of writing

events = Event.objects.annotate(
    paid_participants=Count('participants', filter=Q(participants__is_paid=True))
)

like the example says, you accidentally write

events = Event.objects.annotate(
    paid_participants=Count('participants'), filter=Q(participants__is_paid=True)
)  # WRONG

then you will get this error message. It’s a silly mistake, but could cost you an hour or two, and ExpressionWrapper won’t help. (Hopefully this helps somebody else.)

Answered By: Leopd
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.