For example, there are Category
and Product
models which have many-to-many relationship as shown below. *I use Django 4.2.1:
# "models.py"
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Product(models.Model):
categories = models.ManyToManyField(Category)
name = models.CharField(max_length=50)
price = models.DecimalField(decimal_places=2, max_digits=5)
Then, there are Category
and Product
admins as shown below:
# "admin.py"
from django.contrib import admin
from .models import Category, Product
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'name')
ordering = ('id',)
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'price')
ordering = ('id',)
Then, Category
admin has 5 objects as shown below:

And, Product
admin has 6 objects as shown below:

Now, define get_products
and get_categories()
with @admin.display(), then set them to list_display in Category
and Product
admins respectively as shown below. *description
argument in @admin.display()
can rename the columns in Django Admin from GET PRODUCTS
and GET CATEGORIES
to PRODUCTS
and CATEGORIES
respectively:
# "admin.py"
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'get_products')
ordering = ('id',) # Here
# Here
@admin.display(description='products')
def get_products(self, obj):
return [product.name for product in obj.product_set.all()]
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin): # Here
list_display = ('id', 'name', 'price', 'get_categories')
ordering = ('id',)
# Here
@admin.display(description='categories')
def get_categories(self, obj):
return [category.name for category in obj.categories.all()]
Then, PRODUCTS
column is displayed in Category
admin as shown below:

Then, CATEGORIES
column is displayed in Product
admin as shown below:

Also, you can display PRODUCTS
and CATEGORIES
columns by defining get_products()
and get_categories()
with @admin.display()
in Category
and Product
models respectively as shown below:
# "models.py"
from django.db import models
from django.contrib import admin
class Category(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
# Here
@admin.display(description='products')
def get_products(self):
return [product.name for product in self.product_set.all()]
class Product(models.Model):
categories = models.ManyToManyField(Category)
name = models.CharField(max_length=50)
price = models.DecimalField(decimal_places=2, max_digits=5)
# Here
@admin.display(description='categories')
def get_categories(self):
return [category.name for category in self.categories.all()]
Then, set them to list_display
in Category
and Product
admins respectively as shown below:
# "admin.py"
...
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'get_products')
ordering = ('id',) # Here
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin): # Here
list_display = ('id', 'name', 'price', 'get_categories')
ordering = ('id',)