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 v
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.
Since django admin uses the db to sort you cant sort on the function you are showing in the list.
What you can do is to add the column you want to show to the queryset that django admin is using to list your models, this way you can have sorting.
To add the column you need you have to use the queryset extra method.
This should do the trick :)
Content.objects.all().extra(select={'twitter_score': 'SELECT score from content_score WHERE content_score.id = content_content.id'})
BONUS ROUND:
Content.objects.all().extra(select={'twitter_score': 'SELECT 'Twitter score:' || score from content_score WHERE content_score.id = content_content.id'})