Custom properties in a query
Given the simplified example below, how would I access my custom "current_status" property within a queryset? Is it even possible?
At the moment, I want to list the all the current Events and show the current status. I can get the property to display in a template ok, but I can't order the queryset by it. Alternatively, would I need to create a custom manager with some kind of nested "if" statement in the 'Select'?
class Event(models.Model):
....
date_registered = models开发者_开发技巧.DateField(null=True, blank=True)
date_accepted = models.DateField(null=True, blank=True)
date_reported = models.DateField(null=True, blank=True)
...
def _get_current_status(self):
...
if self.date_reported:
return "Reported"
if self.date_accepted:
return "Accepted"
if self.date_registered:
return "Registered"
if self.date_drafted:
return "Drafted"
current_status = property(_get_current_status)
Instead of calculating the status as a property, create a proper model field for it and update it in the save method. Then you can use that field directly in the query.
You cannot use a custom property in query, since Django's ORM will try to map it to a database column and fail. Of course you can use it in an evaluated queryset, e.g. when you're iterating about the objects of a query's results!
You can only filter for things like: Event.objects.filter(date_drafted__isnull=False)
.
http://docs.djangoproject.com/en/dev/ref/models/querysets/#isnull
Thanks to Daniel. I think that I might use your approach. However, I also managed to get it working using the queryset 'extra' method, which might also be useful to other people, although its probably isn't database agnostic.
qs = Event.objects.extra(select={'current_status_id':
'''(CASE
WHEN date_cancelled THEN 0
WHEN date_closed THEN 6
WHEN date_signed_off THEN 5
WHEN date_reported THEN 4
WHEN date_accepted THEN 3
WHEN date_registered THEN 2
WHEN date_drafted THEN 1
ELSE 99
END)
'''})
精彩评论