Django - 网上商店模型组织

时间:2013-08-21 23:59:07

标签: django django-models

我开始在Django中创建一个Web商店。它将有不同种类的产品,如衬衫,海报,马克杯,贴纸。每种类型的产品都有不同的领域。例如:衬衫将有尺寸和颜色选择,贴纸将有尺寸选项,海报和马克杯将没有选择。

最好的方法是什么?遗产?的关系?

在我深入研究这类项目之前,我还在学习Django并想从更有经验的人那里了解这些。

由于

1 个答案:

答案 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。这将有助于您在ClothingItemItem上生成聚合,但是只要您想获取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类。)