例如,下面展示了具有多对多关系的
Category
和
Product
模型。*我使用的是
Django 4.2.1版本。
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)
然后,下面展示了
Category
和
Product
的管理员:
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',)
然后,
Category
管理员有以下 5 个对象:
![enter image description here](https://istack.dev59.com/a443T.webp)
而且,“产品”管理员有6个对象,如下所示:
![enter image description here](https://istack.dev59.com/vmSi8.webp)
现在,使用
@admin.display()定义
get_products
和
get_categories()
,然后将它们分别设置为
Category
和
Product
管理员中的
list_display,如下所示。在
@admin.display()
中的
description
参数可以将Django Admin中的列名从
GET PRODUCTS
和
GET CATEGORIES
重命名为
PRODUCTS
和
CATEGORIES
:
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'get_products')
ordering = ('id',)
@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):
list_display = ('id', 'name', 'price', 'get_categories')
ordering = ('id',)
@admin.display(description='categories')
def get_categories(self, obj):
return [category.name for category in obj.categories.all()]
然后,在“类别”管理中,如下所示显示了“产品”列:
![enter image description here](https://istack.dev59.com/ABflF.webp)
然后,CATEGORIES
列显示在Product
管理页面中,如下所示:
![enter image description here](https://istack.dev59.com/bj3FL.webp)
此外,您可以通过在Category和Product模型中分别定义get_products()和get_categories()函数,并使用@admin.display()来显示PRODUCTS和CATEGORIES列,如下所示:
同样地,您可以通过在Category和Product模型中分别定义get_products()和get_categories()函数,并使用@admin.display()来显示PRODUCTS和CATEGORIES列,如下所示:
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
@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)
@admin.display(description='categories')
def get_categories(self):
return [category.name for category in self.categories.all()]
然后,将它们分别设置为
Category
和
Product
管理员中的
list_display
,如下所示:
...
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'get_products')
ordering = ('id',)
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'price', 'get_categories')
ordering = ('id',)
ModelAdmin
实现一个经过优化的get_queryset()
方法,详见https://dev59.com/Fmct5IYBdhLWcg3wF5tF#12354293。 - goetzcached_property
会有所帮助。但我认为可能不会。当您使用优化的get_queryset
时,您可以在那里进行注释/预处理数据,例如在 SQL 中执行产品连接而不是在 Django 中,并将自定义数据存储在查询集中。然后,当访问该属性时,您只需要在 SQL 中执行一次逻辑,而不是对每行都执行一次。 - goetzget_queryset
,只是我还没有找到一个足够简单的示例来说明我应该做什么,也没有时间去阅读完整的文档。 - Sebastián Vansteenkiste