6

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?

djvg
  • 11,722
  • 5
  • 72
  • 103

2 Answers2

13

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.

djvg
  • 11,722
  • 5
  • 72
  • 103
2

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

Leopd
  • 41,333
  • 31
  • 129
  • 167
  • Good point. The `events` queryset is created without issue, but the error is raised when you try to evaluate it, e.g. `events.first()`. – djvg Jan 30 '23 at 07:54