类别过滤器和商店项目选项 Django

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

我不知道如何为 Django 商店的每个产品类别制作过滤器。

假设我们有一个类别“phones”,这个类别应该有过滤器:屏幕尺寸、操作系统、品牌等。 我们还有一个类别“plywood”,其过滤器应如下所示:厚度、等级、尺寸等。我如何构建这样的架构,以便可以通过 Django 管理面板创建:存储项目,项目参数(用于将来过滤),项目类别,项目类别的一组过滤器。我们需要一个可扩展的解决方案来解决这个问题。请帮忙!我不经常在这个资源上提问,但是我在这里已经花了 4 天,但没有找到解决这个问题的方法。

我尝试了很多不同的东西,例如,我尝试创建一个包含所有可能过滤器的 BooleanField 的 CategoryOptions(类别选项)模型,然后基于设置为 True 的 BooleanFields,我尝试动态生成字段ItemOptions(存储项目选项)模型基于 CategoryOptions 模型。这是我一次不成功尝试的代码(草图)-




class CategoryOptions(models.Model):
    size = models.BooleanField(db_index=True, default=False)
    format = models.BooleanField(db_index=True, default=False)
    type = models.BooleanField(db_index=True, default=False)
    thickness = models.BooleanField(db_index=True, default=False)
    brand = models.BooleanField(db_index=True, default=False)
    operation_system = models.BooleanField(db_index=True, default=False)

    class Meta:
        verbose_name = 'Category options'

    def get_option_names(self):
        # return a list of the names of the fields that are set to True
        option_names = []
        for field in self._meta.fields:
            if isinstance(field, models.BooleanField) and getattr(self, field.name):
                option_names.append(field.name)
        return option_names


class Filters(models.Model):
    name = models.CharField(max_length=100, db_index=True)
    options = models.ForeignKey(CategoryOptions, on_delete=models.CASCADE)

    class Meta:
        verbose_name = 'Filter'
        verbose_name_plural = 'Filters'

    def __str__(self):
        return self.name


class Category(models.Model):
    name = models.CharField(max_length=30, db_index=True)
    filters = models.ForeignKey(Filters, on_delete=models.CASCADE)
    slug = models.SlugField(null=True, blank=True, editable=False)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super().save(*args, **kwargs)

    class Meta:
        verbose_name = 'Category'
        verbose_name_plural = 'Categories'

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('products:category', kwargs={'category_slug': self.slug})


class ItemOptions(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

    class Meta:
        verbose_name = 'Item options'
        verbose_name_plural = 'Items options'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Dynamically generate fields based on the options selected in the related Category instance
        for option in self.category.filters.options.get_option_names():
            field = models.CharField(max_length=60, db_index=True, verbose_name=option, null=True, blank=True)
            self.add_to_class(option, field)


class Items(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    options = models.ForeignKey(ItemOptions, on_delete=models.CASCADE)

    title = models.CharField(max_length=60, db_index=True)
    description = models.TextField(blank=True)
    price = models.SmallIntegerField()

    in_stock_amount = models.SmallIntegerField(default=0)

    image = models.ImageField(upload_to='products_images/%Y/%m/%d', blank=True)
    slug = models.SlugField(null=True, blank=True, editable=False)

    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        if not self.pk:
            super().save(*args, **kwargs)
        self.slug = f'{slugify(self.title)}-{self.pk}'
        super().save(*args, **kwargs)

    class Meta:
        verbose_name = 'Item'
        verbose_name_plural = 'Items'

    def __str__(self):
        return self.title


这是我得到错误的地方

RelatedObjectDoesNotExist at /admin/products/itemoptions/add/

ItemOptions has no category.
python django django-orm django-filter marketplace
© www.soinside.com 2019 - 2024. All rights reserved.