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)
at the end of the django-admin startproject command: (env) $ django-admin startproject <projectname> . The dot skips the top-level project folder and creates your management app and the manage.py file right inside your current working directory. You might encounter this syntax in some online Django tutorials.
For Django 1.4-1.7, list_filter allows you to use a subclass of SimpleListFilter . It should be possible to create a simple list filter that lists the values you want.
.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()
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
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