I'm trying to sort a Django Admin list page by a specific value in the objects' related foreign key set.
Specifically, in the below code, I want the ContentAdmin view to show a list of all content objects sorted by the "Twitter Score" (The Score object with name "Twitter").
In the django app I have the following models:
class Content(models.Model):
body = models.CharField(max_length=564)
title = models.CharField(max_length=64)
class Score(models.Model):
name = models.CharField(max_length=64)
score = models.IntegerField()
content = models.ForeignKey('Content')
And in the admin.py I have the following:
class ContentAdmin(admin.ModelAdmin):
list_display = ('title', 'show_twitter_score',)
def show_twitter_score(self, obj):
twitter_score = obj.score_set.get(name='Twitter')
return 'Twitter: ' + str(twitter_score.score)
GOAL: The admin panel for ContentAdmin displays the content objects ordered by "Twitter" scores
Thanks everyone!
I solved this by extending the get_queryset
method of the ContentAdmin
class. After that, it was just a matter of getting the right ORM query
def get_queryset(self, request):
qs = super(ContentAdmin, self).get_queryset(request)
return qs.filter(score__name='Twitter').order_by('-score__score')
For Django 1.5 and earlier, the method was queryset
.
def queryset(self, request):
qs = super(ContentAdmin, self).queryset(request)
return qs.filter(score__name='Twitter').order_by('-score__score')
If I understand correctly, you can try this from ModelAdmin.list_display in Django's documentation:
Usually, elements of
list_display
that aren't actual database fields can't be used in sorting (because Django does all the sorting at the database level).However, if an element of
list_display
represents a certain database field, you can indicate this fact by setting theadmin_order_field
attribute of the item.For example:
class Person(models.Model): first_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) def colored_first_name(self): return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name) colored_first_name.allow_tags = True colored_first_name.admin_order_field = 'first_name' class PersonAdmin(admin.ModelAdmin): list_display = ('first_name', 'colored_first_name')
The above will tell Django to order by the first_name field when trying to sort by colored_first_name in the admin.
You can try this workaround in your code for the sorting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With