根据产品选择在 Django Admin 中过滤相关颜色

问题描述 投票:0回答:1

问题陈述:

我正在开发一个 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

遇到的问题:

虽然过滤逻辑似乎是正确的,但我面临以下挑战:

  1. 当我尝试创建或编辑

    product_varients
    时,
    Color
    字段无法正确显示。
    它显示所有产品,而不是排除那些已链接到颜色的产品。

  2. 我想确保当我创建新的

    Color
    时,它只显示尚未具有与其关联的颜色的产品。

问题:

  1. 如何正确过滤 Django 管理中的

    product_varients
    字段,使其仅显示尚未与所选颜色关联的产品?

  2. 有没有更好的方法在 Django 管理界面中实现这种过滤?

python django django-models django-forms django-admin
1个回答
0
投票

您面临的主要问题是如何过滤产品的现有颜色和新颜色。但是,您当前的实现没有处理正确的排除登录,因为 .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  
            )         

© www.soinside.com 2019 - 2024. All rights reserved.