简体   繁体   English

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

[英]Django: Model with varying fields (Entity-Attribute-Value model)

I have the following Django model to store sparse product data in a relational database. 我有以下Django模型将稀疏产品数据存储在关系数据库中。 I apologize myself for any wrong relationship in the code below (ForeignKey and/or ManyToMany might be wrongly placed, I am just playing around with Django for now). 对于以下代码中的任何错误关系,我深表歉意(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)

The idea is to store the name , stock and price for each product in one table and the information for each product in the ( id , value ) format in another table. 想法是将每个产品的名称库存价格存储在一个表中,并将每个产品的信息以( idvalue )格式存储在另一个表中。

I do know, a priori, the fields that each product category should have. 我确实知道每个产品类别应具有的字段。 For instance, a product of type Desktop should have, among others, memory size and storage size as fields, whereas another product of category Monitor should have resolution and screen size as fields. 例如, Desktop类型的产品应将内存大小存储大小作为字段,而Monitor类的另一产品应将分辨率屏幕大小作为字段。

My question is: How do I guarantee, in Django, that each product contains only the fields for its category? 我的问题是:在Django中,如何保证每个产品仅包含其类别的字段? More precisely, when specifying a product of category Monitor , how to assure that only resolution and screen size are fields in the ProdData table? 更准确地说,当指定类别Monitor的产品时,如何确保ProdData表中的字段仅是分辨率屏幕尺寸

I found a similar question Django: Advice on designing a model with varying fields , but there was no answer on how to assure the above. 我发现了一个类似的问题Django:有关设计具有不同字段的模型的建议 ,但是没有关于如何确保上述内容的答案。

Thank you in advance. 先感谢您。

Django is an excellent framework, but it is still just an abstraction over a relation database. Django是一个出色的框架,但它仍然只是关系数据库的抽象。

What you are asking isn't efficiently possible in a relational database, so it will be tough to do in Django. 您所要询问的内容在关系数据库中不可能高效实现,因此在Django中很难做到。 Primarily, because at some point your code will need to be converted to tables. 主要是因为在某些时候您的代码将需要转换为表。

There are basically 2 ways you can do this: 基本上有两种方法可以执行此操作:

  1. A product class with a ManyToMany relation to an attribute table: 与属性表具有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" 

    But, your logic around certain classes of objects having certain properties will be lost. 但是,围绕具有某些属性的某些类的对象的逻辑将丢失。

  2. Use inheritance. 使用继承。 Django is just Python, and inheritance is certainly possible - in fact its encouraged : Django只是Python,继承当然是可能的- 实际上,它受到鼓励

     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) 

    Then you can do queries on all products - Products.objects.all() - or just Monitors - Monitor.objects.all()` - and so on. 然后你就可以对所有的产品做查询- Products.objects.all() -或者只是监视器- Monitor.objects.all()` -等。 This hard codes the possible products in code, so a new product type requires a database migration, but it also gives you the ability to embed your business logic in the models themselves. 这用代码对可能的产品进行了硬编码,因此,新的产品类型需要进行数据库迁移,但是它还使您能够将业务逻辑嵌入模型本身。

There are trade-offs to both these approaches which you need to decide, so picking is up to you. 这两种方法都需要权衡取舍,因此选择取决于您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM