Reputation: 3063
I would like to show the count of related objects in django's list_display property. for example we have a category field and we want to show how many blog posts are posted in this category
I have tried this so far:
admin.py:
from .models import Category
class CategoryAdmin(admin.ModelAdmin):
def category_post_count(self, obj):
return obj.post_set.count
category_post_count.short_description = "Posts Count"
list_display = ['category', 'category_post_count']
models.py:
class Category(models.Model):
category = models.CharField(max_length=25)
class Post(models.Model):
category = models.ForeignKey(Category, null=True, blank=False)
Upvotes: 23
Views: 13228
Reputation: 821
Although the accepted answer will produce the expected result, this is not how it should be done in most cases because it will generate a "n+1" problem, a.k.a one more sql query per row.
You should modify your admin class (or manager if you need it in more situations than just the admin) to retrieve a count annotation (which is django's term for aggregate columns) and then use this value. It will compute the count in the main select query, avoiding generation of non necessary queries.
...
from django.db.models import Count
...
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = [..., 'post_count']
...
def post_count(self, obj):
return obj.post_count
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(post_count=Count("post"))
return queryset
Upvotes: 35
Reputation: 52183
.count
is a function so you have to call it by appending parentheses ()
at the end:
def category_post_count(self, obj):
return obj.post_set.count()
Upvotes: 18