﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
30542	Float-valued aggregations and annotations with filters fail with AttributeError	Chuan-Zheng Lee	Étienne Beaulé	"When any float-valued aggregation or annotation (`Avg`, `StdDev`, `Variance`) is used with the `filter=` keyword argument, the following exception is raised:
{{{
AttributeError: 'WhereNode' object has no attribute 'output_field'
}}}

For example, these queries all fail with this error:
{{{#!python
Speaker.objects.annotate(average=Avg('speakerscore__score', filter=Q(speakerscore__ghost=False)))
Speaker.objects.annotate(average=StdDev('speakerscore__score', filter=Q(speakerscore__ghost=False)))
Team.objects.annotate(average=Avg('debateteam__teamscore__score', filter=Q(debateteam__teamscore__forfeit=False)))
}}}

The error seems to be raised irrespective of what's in the database (''e.g.'', it's raised even for an empty database). However, it doesn't affect aggregations like `Sum`, `Max` or `Min` that don't use `NumericOutputFieldMixin`. Also, queries that don't use the `filter=` keyword in the aggregation work fine.

The exception in question is raised from line 46 of django/db/models/functions/mixins.py, which looks for an `output_field` attribute of every element of `self.get_source_expressions()`, where `self` is the object containing `NumericOutputFieldMixin`, in this case `Avg` or some other subclass of `Aggregate`. But `Aggregate.get_source_expressions()` includes `self.filter` in its list, and (post-compilation) `self.filter` is a `WhereNode`, which doesn't have an `output_field` attribute.

This issue is new in version 2.2. Everything works fine in version 2.1 (where I believe `NumericOutputFieldMixin` didn't exist, or at least wasn't on the MRO for `Avg`, `StdDev` or `Variance`).

=== Minimal reproducible example

In a blank (or any) project, insert in models.py:
{{{#!python
from django.db.models import Model, FloatField, BooleanField

class Book(Model):
    price = FloatField()
    fiction = BooleanField()
}}}
then run migrations and in `python manage.py shell`:
{{{
$ python manage.py shell
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type ""help"", ""copyright"", ""credits"" or ""license"" for more information.
(InteractiveConsole)
>>> from django22_output_field_bug.models import Book
>>> from django.db.models import Avg, Q
>>> Book.objects.annotate(average=Avg('price', filter=Q(fiction=True)))
Traceback (most recent call last):
[...]
  File ""/[...]/django/db/models/functions/mixins.py"", line 46, in <genexpr>
    if any(isinstance(s.output_field, DecimalField) for s in source_expressions):
AttributeError: 'WhereNode' object has no attribute 'output_field'
>>> Book.objects.aggregate(average=Avg('price', filter=Q(fiction=True)))
Traceback (most recent call last):
[...]
  File ""/[...]/django/db/models/functions/mixins.py"", line 46, in <genexpr>
    if any(isinstance(s.output_field, DecimalField) for s in source_expressions):
AttributeError: 'WhereNode' object has no attribute 'output_field'
}}}
"	Bug	closed	Database layer (models, ORM)	2.2	Release blocker	fixed	aggregation, annotation, filter		Accepted	1	0	0	0	0	0
