我开始在Django中创建一个Web商店。它将有不同种类的产品,如衬衫,海报,马克杯,贴纸。每种类型的产品都有不同的领域。例如:衬衫将有尺寸和颜色选择,贴纸将有尺寸选项,海报和马克杯将没有选择。
最好的方法是什么?遗产?的关系?
在我深入研究这类项目之前,我还在学习Django并想从更有经验的人那里了解这些。
由于
答案 0 :(得分:3)
这是一个有趣的问题。我相信首先你必须知道你的用户是想自己添加项目类型,还是有预定义数量的类型,只有开发人员可以根据需要添加新项目。
静态项目类型
如果项类型是静态的,则可以使用模型继承来创建模式。因此,在这种情况下,我建议为每种项目类型定义一个或多个抽象基础模型和具体模型。例如,你会做这样的事情:
class Item(models.Model): slug = models.SlugField() price = models.DecimalField() remaining = models.IntegerField() description = models.CharField() class Meta: abstract=True class ClothingItem(Item): size = models.CharField() brand = models.CharField() class Meta: abstract=True class Jacket(ClothingItem): has_hood = models.BooleanField() class Hat(ClothingItem): hat_type = models.CharField(choices=[])
因此,上面实际上只生成两个数据库表:Jacket和Hat,每个表都包含它继承的模型中的所有字段。这是大多数人在django中使用的,因为它非常干净,因此很容易添加表单并生成查询以获取项目。
您的其他选择是不使用抽象基类,因此您将获得一个名为Item
的数据库表,其中包含每个字段,另一个名为ClothingItem
的表将包含一个ForeignKey到{{ 1}}和另一个名为Item
的{{1}}将包含Jacket
的ForeignKey。这将有助于您在ClothingItem
或Item
上生成聚合,但是只要您想获取Jacket的属性,django就必须查询三个表(带连接)。我建议只有在你需要的时候才能使用它。
动态项类型 在这种情况下,您必须使用不同的模式,因为必须由应用程序的用户定义Items的属性。你可以这样做:
class Category(models.Model): name = models.CharField() class Attribute(models.Model): category = models.ForeignKey(Category) name = models.CharField class Item(models.Model): slug = models.SlugField() price = models.DecimalField() remaining = models.IntegerField() category = models.ForeignKey(Category) description = models.CharField() attributes = models.ManyToManyField(Attribute, through='ItemAttribute') class ItemAttribute(models.Model): item= models.ForeignKey(Item) attribute = models.ForeignKey(Attribute) value = models.CharField()
这种设计稍微复杂一些。我们这里有一个类别模型,它将定义您的项目类型(帽子,夹克,马克杯,衬衫,海报等) - 您还可以定义类别的层次结构,我将作为练习留给您。属性模型定义属性的名称 - 每个属性都有一个名称和它所属的类别。因此,对于夹克类别,您将具有has_hood属性,对于帽子类别,您将具有hat_type属性等。
现在,Item模型也属于Category,并且通过ItemAttribute模型与Attribute模型有多对多的关系。最后一个意味着你将有一个 数据库中的ItemAttribute表,包含以下字段:
item - attribute - value
因此夹克312将具有值为true的属性2(has_hood),而夹克313将具有值为false等的属性2。
上述设计存在一个小问题,即属性中没有“类型”。您应该通过向Attribute模型添加_type属性来扩展它。 另外,请检查此问题的答案: Django dynamic model fields以更通用的方式定义动态模型字段。
通过此设计,您的用户将能够创建新属性,将其分配到类别,因此当他们添加新项目时,他们将能够根据其类别填充其属性。当然,要使用户能够执行此操作,您还必须生成包含每个项目的动态属性的动态表单。如果你愿意,我也可以告诉你如何做到这一点 - 它并不像最初有人认为的那么困难(提示:使用ClothingItem
来生成动态Form类。)