#24420 closed Bug (fixed)
Can't order_by annotated field if annotated field uses conditional expression
Reported by: | Kris Fields | Owned by: | Josh Smeaton |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.8beta1 |
Severity: | Normal | Keywords: | order_by, annotation, conditional expression |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Continuing with the Client example on https://docs.djangoproject.com/en/dev/ref/models/conditional-expressions/
from django.db import models class Client(models.Model): REGULAR = 'R' GOLD = 'G' PLATINUM = 'P' ACCOUNT_TYPE_CHOICES = ( (REGULAR, 'Regular'), (GOLD, 'Gold'), (PLATINUM, 'Platinum'), ) name = models.CharField(max_length=50) registered_on = models.DateField() account_type = models.CharField( max_length=1, choices=ACCOUNT_TYPE_CHOICES, default=REGULAR, ) Client.objects.annotate( discount=Case( When(account_type=Client.GOLD, then=Value('5%')), When(account_type=Client.PLATINUM, then=Value('10%')), default=Value('0%'), output_field=CharField(), ), ).order_by('discount')
Error is:
<repr(<django.db.models.query.QuerySet at 0x10afaef10>) failed: AttributeError: 'WhereNode' object has no attribute 'resolve_expression'>
Change History (5)
comment:1 by , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 10 years ago
Component: | Uncategorized → Database layer (models, ORM) |
---|---|
Has patch: | set |
Triage Stage: | Accepted → Ready for checkin |
Seems like a candidate for backport.
comment:4 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Note:
See TracTickets
for help on using tickets.
See: https://github.com/django/django/pull/4239
Funnily enough, being explicit worked before this patch:
CaseTestModel.objects.filter(integerlte=2).annotate(test=Case(
The problem is that the same instance of each
When
clause has resolve_expression called on it multiple times. Once for the annotation, and once again for the order_by. The problem is that When.resolve_expression converts the Q() into a WhereNode(), and overwrites the condition property. It's not idempotent.