我有以下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)格式存储在另一个表中。
我确实知道每个产品类别应具有的字段。例如,Desktop类型的产品应将内存大小和存储大小作为字段,而Monitor类的另一产品应将分辨率和屏幕大小作为字段。
我的问题是:在Django中,如何保证每个产品仅包含其类别的字段?更准确地说,当指定类别Monitor的产品时,如何确保ProdData表中的字段仅是分辨率和屏幕尺寸?
我发现了一个类似的问题Django:有关设计具有不同字段的模型的建议,但是没有关于如何确保上述内容的答案。
先感谢您。
Django是一个出色的框架,但它仍然只是关系数据库的抽象。
您所要询问的内容在关系数据库中不可能高效实现,因此在Django中很难做到。主要是因为在某些时候您的代码将需要转换为表。
基本上有两种方法可以执行此操作:
一个product
与类ManyToMany
关系的属性表:
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"
但是,围绕具有某些属性的某些类的对象的逻辑将丢失。
使用继承。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)
然后,您可以查询所有产品-Products.objects.all()
或仅查询Monitors-Monitor.objects.all()`-等等。这会用代码对可能的产品进行硬编码,因此,新的产品类型需要进行数据库迁移,但是它还使您能够将业务逻辑嵌入模型本身。
这两种方法都需要权衡取舍,因此选择取决于您。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句