我开始在 Django 中创建一个网上商店。它将有不同种类的产品,如衬衫、海报、杯子、贴纸。每种类型的产品都有不同的字段。例如:衬衫有尺寸和颜色选项,贴纸有尺寸选项,海报和杯子没有选项。
做这个的最好方式是什么?遗产?关系?
我仍在学习 Django,并希望在深入研究此类项目之前从更有经验的人那里了解这一点。
谢谢
我开始在 Django 中创建一个网上商店。它将有不同种类的产品,如衬衫、海报、杯子、贴纸。每种类型的产品都有不同的字段。例如:衬衫有尺寸和颜色选项,贴纸有尺寸选项,海报和杯子没有选项。
做这个的最好方式是什么?遗产?关系?
我仍在学习 Django,并希望在深入研究此类项目之前从更有经验的人那里了解这一点。
谢谢
这是一个有趣的问题。我相信首先您必须确定您的用户是否愿意自己添加项目类型,或者是否会有预定义数量的类型,并且只有开发人员可以在需要时添加新的类型。
静态项目类型
如果项目类型是静态的,您可以使用模型继承来创建您的模式。因此,在这种情况下,我建议为每个项目类型定义一个或多个抽象基础模型和具体模型。例如你会做这样的事情:
类项目(模型。模型): 蛞蝓 = 模型.SlugField() 价格 = 模型.DecimalField() 剩余 = 模型.IntegerField() 描述 = 模型.CharField() 元类: 抽象=真 类服装项目(项目): 大小 = 模型.CharField() 品牌 = 模型.CharField() 元类: 抽象=真 类夹克(服装项目): has_hood = models.BooleanField() 类帽子(服装项目): hat_type = models.CharField(choices=[])
因此,上面实际上只会生成两个数据库表:Jacket 和 Hat,每一个都将包含它继承的模型中的所有字段。这是大多数人在 django 中使用的,因为它非常干净,使得添加表单和生成查询以获取项目非常容易。
您的其他选择是不使用抽象基类,因此您将获得一个名为的数据库表Item
,该表将包含每个字段,另一个名为ClothingItem
的表将包含一个 ForeignKeyItem
和另一个命名Jacket
的表将包含一个 ForeignKey ClothingItem
。这将帮助您在Item
or上生成聚合ClothingItem
,但是当您想要获取 Jacket 的属性时,django 将不得不查询三个表(带有连接)。我建议仅在您确定需要它时才使用它。
动态项目类型 在这种情况下,您必须使用不同的模式,因为项目的属性必须由应用程序的用户定义。你可以这样做:
类类别(模型。模型): 名称 = 模型.CharField() 类属性(models.Model): 类别=模型.ForeignKey(类别) 名称 = 模型.CharField 类项目(模型。模型): 蛞蝓 = 模型.SlugField() 价格 = 模型.DecimalField() 剩余 = 模型.IntegerField() 类别=模型.ForeignKey(类别) 描述 = 模型.CharField() 属性 = models.ManyToManyField(属性,通过='ItemAttribute') 类 ItemAttribute(models.Model): item=models.ForeignKey(Item) 属性 = 模型.ForeignKey(属性) 值 = 模型.CharField()
这种设计稍微复杂一些。我们这里有一个类别模型,它将定义您的项目类型(帽子、夹克、杯子、衬衫、海报等)——您还可以定义类别的层次结构,我将把它留给您作为练习。属性模型定义了属性的名称——每个属性都有一个名称和它所属的类别。因此,对于夹克类别,您将拥有一个 has_hood 属性,对于帽子类别,您将拥有一个 hat_type 属性等。
现在,一个 Item 模型也属于一个 Category 并且通过 ItemAttribute 模型与 Attribute 模型具有多对多的关系。最后一个意味着您将在数据库中拥有一个 ItemAttribute 表,其中包含以下字段:
项目 - 属性 - 值
因此夹克 312 将具有值为 true 的属性 2(has_hood),而夹克 313 将具有值为 false 等的属性 2。
上面的设计有个小问题,就是属性中没有“类型”。您应该通过将 _type 属性添加到 Attribute 模型来进一步扩展它。另外,请检查这个问题的答案: Django 动态模型字段,它以更通用的方式定义动态模型字段。
通过这种设计,您的用户将能够创建新属性,将它们分配给类别,因此当他们添加新项目时,他们将能够根据他们的类别填充他们的属性。当然,为了让您的用户能够做到这一点,您还必须生成包含每个项目的动态属性的动态表单。如果你愿意,我也可以告诉你如何做到这一点——它并不像人们起初认为的那么难(提示:用于type
生成动态 Form 类)。