python - Django:具有不同字段的模型(实体-属性-值模型)

标签 python django entity-attribute-value

我有以下 Django 模型来将稀疏产品数据存储在关系数据库中。对于下面代码中的任何错误关系,我深表歉意(ForeignKey 和/或 ManyToMany 可能放置错误,我现在只是在玩 Django)。

class ProdCategory(models.Model):
    category = models.CharField(max_length=32, primary_key=True)

class ProdFields(models.Model):
    categoryid = models.ForeignKey(ProdCategory)
    field = models.CharField(max_length=32)

class Product(models.Model):
    name = models.CharField(max_length=20)
    stock = models.IntegerField()
    price = models.FloatField()

class ProdData(models.Model):
    prodid = models.ManyToManyField(Product)
    fieldid = models.ManyToManyField(ProdFields)
    value = models.CharField(max_length=128)

这个想法是将每种产品的名称库存价格存储在一个表中,并将每种产品的信息存储在 ( id, value) 格式在另一个表中。

我确实知道每个产品类别应该具有的字段。例如,桌面类型的产品应将内存大小存储大小作为字段,而类别的另一个产品>显示器应将分辨率屏幕尺寸作为字段。

我的问题是:在 Django 中,如何保证每个产品仅包含其类别的字段?更准确地说,当指定监视器类别的产品时,如何确保ProdData表中只有分辨率屏幕尺寸字段?

我发现了类似的问题Django: Advice on designing a model with varying fields ,但没有回答如何保证上述内容。

提前谢谢您。

最佳答案

Django 是一个优秀的框架,但它仍然只是关系数据库的抽象。

你所要求的在关系数据库中是不可能有效实现的,所以在 Django 中很难做到。主要是因为在某些时候您的代码需要转换为表。

基本上有两种方法可以做到这一点:

  1. 与属性表具有 ManyToMany 关系的 product 类:

    class Product(models.Model):
        name = models.CharField(max_length=20)
        stock = models.IntegerField()
        price = models.FloatField()
        product_type = models.CharField(max_length=20)  eg. Monitor, desktop, etc...
        attributes = models.ManyToManyField(ProductAttribute)
    class ProductAttribute(models.Model):
        property = models.CharField(max_length=20) # eg. "resolution"
        value = models.CharField(max_length=20) # eg. "1080p"
    

    但是,您围绕具有某些属性的某些对象类的逻辑将会丢失。

  2. 使用继承。 Django 只是 Python,继承当然是可能的 - in fact its encouraged :

    class Product(models.Model):
        name = models.CharField(max_length=20)
        stock = models.IntegerField()
        price = models.FloatField()
    
    class Desktop(Product):
        memory_size = models.CharField(max_length=20)
        storage_size = models.CharField(max_length=20)
    class Monitor(Product):
        resolution = models.CharField(max_length=20)
        screen_size = models.CharField(max_length=20)
    

    然后您可以对所有产品进行查询 - Products.objects.all() - 或仅对监视器进行查询 - Monitor.objects.all()` - 等等。这将可能的产品硬编码在代码中,因此新的产品类型需要数据库迁移,但它也使您能够将业务逻辑嵌入到模型本身中。

这两种方法都需要权衡,您需要做出权衡,因此选择取决于您。

关于python - Django:具有不同字段的模型(实体-属性-值模型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33660936/

相关文章:

python - 如何在django中过滤没有被关注的用户

javascript - 仅在选中复选框时显示列表

python - Django 数据迁移与 models.py 不匹配

python - Django 重定向功能保留旧的 url 路径

MySQL:如何转换为 EAV?

MySQL - 带有 IN 子句的查询表现不佳

python - 如何从 python(3) 中的 unicode 字符串打印 unicode 转义序列?

python - "not all arguments converted during string formatting"当to_sql

php - Magento 安装脚本中的 ALTER TABLE 不使用 SQL

python - 什么决定了动态实例的启动时间,如果代码相同,它可以在几周之间变化吗