我正在开发一个用于在Django中存储产品信息的目录应用程序。
这里的挑战是目录中有很多产品,每个产品都有自己的属性。由于这是应用程序的关键部分,并且围绕它构建了很多,我希望它的设计尽可能好。
我知道在Django中有几种处理方法,但我想知道其他人在这些选项中遇到的问题。
我可以创建一个包含所有基本属性的抽象类,并让其他类从该类派生。
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(max_length=1000)
price = models.DecimalField()
class Meta:
abstract = True
class Phone(Product):
series = models.CharField(max_length=100)
这将是最简单的选择,但这将包括Django Forms和Views中的大量工作。
这也将为每个Product子类创建一个表,因此当更改Product类时,所有其他表也必须更改。
这里的Product类不是抽象的,这意味着也可以使用这个类。
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(max_length=1000)
price = models.DecimalField()
class Phone(Product):
series = models.CharField(max_length=100)
这也很简单,但这仍然意味着在表格和视图中有很多工作 这将首先为Product类创建一个表,然后为每个Product子类创建一个表。
前两个选项也会破坏DRY原则,因为必须将属性添加到每个可能对某些类通用但不是所有类通用的Product子类中。
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(max_length=1000)
price = models.DecimalField()
# attributes for phones, tv's, etc...
series = models.CharField(max_length=100)
class PhoneForm(forms.ModelForm):
class Meta:
model = Product
fields = ['name', 'description', 'price', 'series']
必须为每个产品子类创建一个新表单。这看起来很简单,但产品型号会变得非常臃肿。
在这种情况下,我也可以使用代理模型。
class ProductBase(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(max_length=1000)
price = models.DecimalField()
class Meta:
abstract = True
class ElectronicsProduct(models.Model):
series = models.CharField(max_length=100)
class Meta:
abstract = True
class Phone(ProductBase, ElectronicsProduct):
pass
这个方法可以解决我上面遇到的干旱问题,但仍然不是最优的。
这是我想要使用的方法,但更多的是能够为产品添加“额外”功能,这些功能太具体而无法放入产品或产品子类中。
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(max_length=1000)
price = models.DecimalField()
class Attribute(models.Model):
name = models.CharField(max_length=100)
class ProductAttribute(models.Model):
product = models.ForeignKey(Product)
attribute = models.ForeignKey(Attribute)
value = models.CharField(max_length=100)
这里的问题是这个方法是否应该用于所有产品属性,因为我认为这会在数据库上增加很多开销。
这里的另一个挑战是价值类型。在这种情况下,我只能使用字符值,所以当我想使用Decimal值或File时会发生什么。
此时可能还有一些我没有想过的方法。所以,如果你知道我不知道的事情,请与我分享。
我不是在寻找任何意见,而是寻求一些解决方案。因此,如果您对此问题有答案,请告诉我们您为何使用您建议的方法。