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',)