Multiple calls to annotate returns only latest annotation when calling select_subclasses.
See original GitHub issueProblem
When making chained calls to annotate() on a single queryset, only the last annotation applied is returned after calling select_subclasses. If you don’t call select_subclasses, you do receive all annotations.
Environment
- Django Model Utils version: 3.1.1
- Django version: 2.0
- Python version: 3.5.2
- Other libraries used, if any: n/a
Code examples
In the sample below, the only annotation that is available in the evaluated queryset is correct_count.
import django
django.setup() # noqa
from django.db.models import Case, When, ExpressionWrapper, FloatField, Sum, Q
from sampleapp import models
correct_count_calc = ExpressionWrapper(
Sum(
Case(
When((Q(answer__correct=True) & Q(answer__quizresult__user__is_superuser=False)), then=1),
default=0
)
), FloatField()
)
answered_count_calc = ExpressionWrapper(
Sum(
Case(
When(answer__quizresult__user__is_superuser=False, then=1.0),
default=0
)
), FloatField()
)
q = models.BaseQuestion.objects.annotate(answered_count=answered_count_calc) \
.annotate(correct_count=correct_count_calc).select_subclasses().first()
print(q.__dict__)
It seems the problem stems from the snippet below, which sets (rather than appending to) the qset._annotated value for each subsequent call to .annotate().
I have a simple fix for this issue here:
https://github.com/digismack/django-model-utils/commit/6a72cebfc02fd19e68c15343fa9647256ad1e0f9
I was unable to get the test suite to run. They all fail with AppRegistryNotReady: Apps aren't loaded yet. If someone would be willing to help me out a bit, I’d love to submit a pull request with tests and such.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:6

Top Related StackOverflow Question
@areyal @digismack Thank you for finding out this issue and possible solutions! I slightly changed the code and it worked (Django==3.1.7, django-model-utils==4.1.1)! You don’t need to fork this repo, just subclass from django.db.models.QuerySet and add InheritanceQuerySetMixin.
@tony Maybe you can take a look at this and let me know what you think?