Ordering Django models by a method in the model
So, say I have models like this:
class Foo(Model): name = CharField(max_length=200) def latest_comment(self): try: object = self.comment_set.latest() if object: return object.when_posted.date() except: return "" class Comment(Model): when_posted = DateTimeField() text = TextField()
Then this is the modelAdmin:
class FooAdmin(ModelAdmin): list_display = ['name', 'latest_comment'] ordering = ['latest_comment'] admin.site.register(Foo, FooAdmin)
It throws an error when I go to the admin site saying that 'latest_comment' was not found in app.Foo. Having it in list_display works fine. So, my question is: Is there a way to order models in list_display by methods of the model? And if so, how?
I haven't tested the code, but just as an idea to try to implement this with overriding the queryset of the ModelAdmin with a annotate function to sort over a field from related field:
class FooAdmin(admin.ModelAdmin): def queryset(self, request): qs = super(FooAdmin, self).queryset(request) return qs.distinct() \ .annotate(date_of_last_comment=Max('comment__date')) \ .order_by('-date_of_last_comment')
Ordering is a SQL-level functionality and your database doesn't know anything about the methods on your model.
However, you can re-sort after the fact by converting your queryset to a list and then using something like sorted. See: http://wiki.python.org/moin/HowTo/Sorting/
For what it's worth though, I doubt the sorted list will work in the admin. I could be wrong, but I'm pretty sure Django needs it to stay a queryset.
From django doc, you could maybe define your own get_ordering method.