Django - 'WhereNode' object has no attribute 'output_field' error
Asked Answered
T

1

15

I am trying to query and annotate some data from my models:

class Feed(models.Model):     # Feed of content
    user = models.ForeignKey(User, on_delete=models.CASCADE)

class Piece(models.Model):    # Piece of content (video or playlist)
    removed = models.BooleanField(default=False)
    feed    = models.ForeignKey(Feed, on_delete=models.CASCADE)
    user    = models.ForeignKey(User, on_delete=models.CASCADE)

Other fields are not used in the following queries so I skipped them here.

In my view I need to get queryset of all feeds of an authenticated user. Annotation should contain quantity of all pieces that are not removed.

Initially, Piece model didn't contain removed field and everything worked great with the queryset like this:

Feed.objects.filter(user=self.request.user).annotate(Count('piece'))

But then I added the field removed to Piece model and needed to count only pieces that were not removed:

Feed.objects.filter(user=self.request.user)
            .annotate(Count('piece'), filter=Q(piece__removed=False))

It gave me the following error:

'WhereNode' object has no attribute 'output_field'

It is only a little fraction of what django outputs on the error page, so if it is not enough, please let me know what else I need to include in my question.

I tried to include output_field with options like models.IntegerField() or models.FloatField() (properly imported) here and there but got some errors which I do not provide here because I believe those actions made no sense.

I am using Django 2.0.3

Torr answered 4/4, 2018 at 5:34 Comment(3)
Your syntax mistake is here, Feed.objects.filter(user=self.request.user) .annotate(Count('piece', filter=Q(piece__removed=False)))Musser
Thank you so much! I looked everywhere, but didn't check those parentheses. I believe your comment should be an answer.Torr
I'm adding this as an answer, so you can accept.Musser
M
34

Your syntax mistake is here,

Feed.objects.filter(user=self.request.user)
            .annotate(Count('piece', filter=Q(piece__removed=False)))

filter needs to apply at Count not at annotate.

Reference from Django's documentation: https://docs.djangoproject.com/en/2.1/topics/db/aggregation/#filtering-on-annotations

Musser answered 4/4, 2018 at 6:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.