Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 852
uncleshelby Avatar asked Jun 11 '12 14:06

uncleshelby


People also ask

What is the purpose of __ Str__ method in Django?

str function in a django model returns a string that is exactly rendered as the display name of instances for that model. # Create your models here. This will display the objects as something always in the admin interface.

Is Django QuerySet ordered?

By default, results returned by a QuerySet are ordered by the ordering tuple given by the ordering option in the model's Meta . You can override this on a per- QuerySet basis by using the order_by method. The result above will be ordered by pub_date descending, then by headline ascending.

What does First () return in Django?

First() returns the first object matched to the QuerySet, and last() returns the last object matched to the QuerySet: from django.contrib.auth.models import User >>> User.objects.filter(is_active=True).first() >>> User.objects.filter(is_active=True).last()


1 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')
like image 194
Tisho Avatar answered Oct 02 '22 09:10

Tisho