问题陈述:
我正在开发一个 Django 项目,其中有两个模型:
Product
和 Color
。 Product
模型通过名为 Color
的字段与 product_varients
模型具有多对多关系。我的目标是根据所选产品过滤 Django 管理界面中的可用颜色。具体来说,我想确保在创建或编辑 Color
时,product_varients
字段仅显示尚未与该产品关联的颜色
型号:
以下是我的模型的相关部分:
from django.db import models
from shortuuid.django.fields import ShortUUIDField
class Color(models.Model):
coid = ShortUUIDField(length=10, max_length=100, prefix="col", alphabet="abcdefgh")
name = models.CharField(max_length=20)
product_varients = models.ManyToManyField('Product', related_name='color_variants', blank=True)
def __str__(self):
return self.name
class Product(models.Model):
pid = ShortUUIDField(length=10, max_length=100, prefix="prd", alphabet="abcdef")
title = models.CharField(max_length=100, default="Apple")
color = models.ManyToManyField(Color, blank=True)
def __str__(self):
return self.title
当前实施:
在我的
admin.py
中,我为 Color
模型实现了一个自定义表单来过滤 product_varients
字段。相关代码如下:
class ColorAdminForm(forms.ModelForm):
class Meta:
model = Color
fields = '__all__'
def __init__(self, *args, **kwargs):
super(ColorAdminForm, self).__init__(*args, **kwargs)
if self.instance.pk: # Editing an existing color
self.fields['product_varients'].queryset = Product.objects.exclude(
color=self.instance # Exclude products that already have this color
)
else: # Creating a new color
self.fields['product_varients'].queryset = Product.objects.all()
class ColorAdmin(admin.ModelAdmin):
form = ColorAdminForm
遇到的问题:
虽然过滤逻辑似乎是正确的,但我面临以下挑战:
当我尝试创建或编辑
product_varients
时,Color
字段无法正确显示。 它显示所有产品,而不是排除那些已链接到颜色的产品。
我想确保当我创建新的
Color
时,它只显示尚未具有与其关联的颜色的产品。
问题:
如何正确过滤 Django 管理中的
product_varients
字段,使其仅显示尚未与所选颜色关联的产品?
有没有更好的方法在 Django 管理界面中实现这种过滤?
您面临的主要问题是如何过滤产品的现有颜色和新颜色。但是,您当前的实现没有处理正确的排除登录,因为 .exclude(color = self.instance) 没有执行您期望的操作。相反,这会查找产品和颜色之间的直接关系,但关系是多对多的通过产品变体
您需要修改查询product_varients字段仅显示尚未链接到当前颜色或其他颜色(如果是新颜色)的产品。
class ColorAdminForm(forms.ModelForm):
class Meta:
model = Color
fields = '__all__'
def __init__(self, *args, **kwargs):
super(ColorAdminForm, self).__init__(*args, **kwargs)
if self.instance.pk: # Editing an existing color
self.fields['product_varients'].queryset =
Product.objects.exclude(
color_variants=self.instance
)
else:
self.fields['product_varients'].queryset=Product.objects.exclude(
color__isnull=False
)