【问题标题】:How to filter product by its Attribute in Django - Django?如何在 Django - Django 中按其属性过滤产品?
【发布时间】:2021-10-11 10:00:32
【问题描述】:

我正在开发一个 Django 电子商务项目,其中产品具有多个属性,例如。尺寸、颜色(单个产品可以有多个不同尺寸和颜色的属性)。不,我正在尝试使用 django_filters 过滤产品,但无法按其属性进行过滤。

产品型号:

class Product(models.Model):
    variations = (
        ('None', 'None'),
        ('Size', 'Size'),
    )
    name = models.CharField(max_length=200, unique=True)
    store = models.ManyToManyField(Store)
    slug = models.SlugField(null=True, blank=True, unique=True, max_length=500)
    sku = models.CharField(max_length=30, null=True)
    tax = models.IntegerField(null=True, blank=True)
    stock = models.CharField(max_length=10, null=True)
    variations = models.CharField(choices=variations, max_length=20)
    short_description = models.CharField(max_length=500, null=True)
    details = RichTextUploadingField(null=True, blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    discounted_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    image = models.ImageField(upload_to='product/images', default='product.png', null=True, 
    blank=True)
    image_one = models.ImageField(upload_to='product/images', null=True, blank=True)
    image_two = models.ImageField(upload_to='product/images', null=True, blank=True)
    image_three = models.ImageField(upload_to='product/images', null=True, blank=True)
    image_four = models.ImageField(upload_to='product/images', null=True, blank=True)
    image_five = models.ImageField(upload_to='product/images', null=True, blank=True)
    tags = models.ManyToManyField(Tags)
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True,
                                 related_name='products')
    status = models.CharField(max_length=20, choices=(('Active', 'Active'), ('Inactive', 
    'Inactive')))
    brand = models.ForeignKey(Brand, on_delete=models.PROTECT, blank=True, null=True)
    offer = models.ForeignKey(Offer, on_delete=models.CASCADE, null=True,
                              blank=True)  # This is used only for filtration

产品属性模型

class ProductAttribute(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    size = models.ForeignKey(Size, on_delete=models.CASCADE, null=True, blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2, validators= 
    [MinValueValidator(1)])
    discounted_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    stock = models.CharField(max_length=10, null=True)

【问题讨论】:

    标签: python django django-models django-rest-framework django-views


    【解决方案1】:

    标准方法是在“产品”模型中定义属性。但是,如果您坚持这样做,代码将是:

    filtered_ProductAttributes=ProductAttribute.objects.filter(size="12")
    products=[filtered_ProductAttribute.product for filtered_ProductAttribute in filtered_ProductAttributes]
    

    如您所见,代码似乎非常低效,因此,正如开头所建议的,将属性放在“产品”模型中,您将拥有:

    products=Product.objects.filter(size="12")
    

    【讨论】:

      【解决方案2】:

      优化模型将帮助您进行过滤。

      根据我的经验,以下模型方法会更合适:

       class Attributes(models.Model):
          name = models.CharField(max_length=50, default=None)
          slug = models.SlugField(max_length=200, unique=True,null=True)
      
      class AttributeTerms(models.Model):
          name = models.CharField(max_length=50, blank =True)
          attribute = models.ForeignKey(Attributes, on_delete=models.CASCADE)  
      
      class Products(models.Model):
          name = models.CharField(max_length=250,null=True, blank=True,)
          slug = models.SlugField(max_length=200, unique=True,null=True)
          
      
      class ProductAttribute(models.Model):
          product = models.ForeignKey(Products,on_delete=models.CASCADE, related_name='attributes', default=None)
          attributes = models.ForeignKey(Attributes,on_delete=models.CASCADE, related_name='attributes', default=None)
          values = models.ForeignKey(AttributeTerms, on_delete=models.CASCADE, related_name='attributes', default=None)
      
      
      
      class ProductVariant(models.Model):
          product = models.ForeignKey(Products,on_delete=models.CASCADE)
          variant = models.ForeignKey(ProductAttribute,on_delete=models.CASCADE, null = True, default=None)
          stock = models.IntegerField(default=None)
          stock_threshold = models.IntegerField()
          price = models.DecimalField(max_digits=10, decimal_places=2)
          sku = models.CharField(max_length= 250, default=None)
          sale_price = models.DecimalField(max_digits=10, decimal_places=2)
         
      

      【讨论】:

        猜你喜欢
        • 2011-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-04
        相关资源
        最近更新 更多