Django: product variants for ecommerce

4.5k Views Asked by At

I'm trying to build an ecommerce and to configure product variants and attributes. In my product variant models, I'd like to access all of the selected attributes from the related product and add a value for each product.

For example, if I create a new product and chosose two attributes for the variants: color and size, I'd like to be able to create dynamically a field for each of them when creating a variant for this product.

Here's what I have in my models.py file:

class Product(models.Model) :
    name = models.CharField(max_length=120)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    image = models.ImageField(upload_to='products')
    allow_variants = models.BooleanField(default=True)
    product_attributes = models.ManyToManyField("attribute")

    def __str__(self) :
        return self.name

    class Meta :
        ordering = ("name",)

class Attribute(models.Model) :
    name = models.CharField(max_length=120)

    def __str__(self) :
        return self.name

    def get_all_attr_variants(self) :
        variants = AttributeVariant.objects.filter(attribute__name=self.name)
        return variants

class AttributeVariant(models.Model) :
    name = models.CharField(max_length=120)
    attribute = models.ForeignKey(Attribute, on_delete=models.CASCADE)

    def __str__(self) :
        return self.name

    class Meta :
        ordering = ('name',)

class ProductVariant(models.Model) :

Please help me if you have any idea of how I could do it.
Thanks!

1

There are 1 best solutions below

4
On

Django does not allow dynamically adding or removing fields. The best way to get this effect is using a "AttibuteValue" class, like this:

class ProductVariant(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)

class ProductAttributeValue(models.Model):
    variant = models.ForeignKey(ProductVariant, on_delete=models.CASCADE)
    attribute = models.ForeignKey(AttributeVariant, on_delete=models.CASCADE)

    value = models.CharField()  # Depending on what type you want

You can easily get all attributes of a variant by selecting ProductAttributeValues with the correct variant and attribute.