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?

Answers


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.


Need Your Help

asp.net ajax, change asp:image imageurl

asp.net ajax

I have an update panel within which a sortable grid is present. While sorting, I have to change an image which shows the sort direction. The sort is an ajax operation initiated by a linkbutton for ...