admin管理员组

文章数量:1435090

I'm currently working on designing a product data model in Django to manage details for industrial machinery. The challenge is that some products share common specifications, while others have additional, unique specifications. Fixing all fields in a single model isn't feasible due to the variability in product attributes.

For instance:

Product A and Product B share attributes like weight, power, and dimensions.

Product C has unique specifications like operating temperature and safety standards, which aren't applicable to all products.

What would be the best approach to design a flexible and scalable data model in Django that accommodates:

  • Shared specifications across multiple products
  • Additional, unique specifications for certain products

I'm currently working on designing a product data model in Django to manage details for industrial machinery. The challenge is that some products share common specifications, while others have additional, unique specifications. Fixing all fields in a single model isn't feasible due to the variability in product attributes.

For instance:

Product A and Product B share attributes like weight, power, and dimensions.

Product C has unique specifications like operating temperature and safety standards, which aren't applicable to all products.

What would be the best approach to design a flexible and scalable data model in Django that accommodates:

  • Shared specifications across multiple products
  • Additional, unique specifications for certain products
Share Improve this question asked Nov 16, 2024 at 17:44 Muhammed RebinMuhammed Rebin 192 bronze badges 2
  • Do you need to filter/count/... the specific ones? – willeM_ Van Onsem Commented Nov 16, 2024 at 17:49
  • I need to filter the products based solely on their category. Additionally, the attribute field names should be unique. – Muhammed Rebin Commented Nov 17, 2024 at 5:47
Add a comment  | 

1 Answer 1

Reset to default 1

Option 1: Entity-Attribute-Value model

Specify the common ones as fields on the product, use an Entity-Attribute-Value (EAV) model [wiki] for the ones that are not common.

You thus can build an Attribute model which is essentially a name (and perhaps some other attributes):

class Attribute(models.Model):
    name = models.CharField(max_length=128, unique=True)

    def __str__(self):
        return self.name

and an AttributeValue model that contains the value per product, like:

class AttributeValue(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    attribute = models.ForeignKey(Attribute, on_delete=models.CASCADE)
    value = models.FloatField()

    def __str__(self):
        return f'{self.product_id} {self.attribute_id}: {self.value}'

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=('product', 'attribute'),
                name='unique_attributes_per_product',
            )
        ]

This thus linearizes the attribute values per product, but the advantage is that you can still effectively filter on these. For example we can retrieve Products with an weight less than 10 (kilograms) with:

Product.objects.filter(
    attributevalue__attribute__name='weight', attributevalue__value__lte=10
)

If you have multiple types of values, I think it makes in that case sense to attach an EAV for each type of value (so a separate one for string-like data).

Option 2: JSON blob

An other option is to add a JSON blob to the data by using a JSONField model field [Django-doc]. The advantage is that it allows to easily dump all sorts of data in the blob per product. The disadvantage is that filtering on JSON blobs is typically not very efficient, and that it is not the most compact way to store and retrieve data from the database: each time you fetch a Product, all attributes are retrieved as well, but that is not per se necessary:

class Product(models.Model):
    # …
    extra_attributes = models.JSONField()

本文标签: How to design a flexible product data model in Django for varying product specificationsStack Overflow