Joh*_*eer 5 python django database-design
我正在开发一个目录应用程序,用于在 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)
Run Code Online (Sandbox Code Playgroud)
这将是最简单的选择,但这将包括 Django 表单和视图中的大量工作。
这还将为每个 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)
Run Code Online (Sandbox Code Playgroud)
这也非常简单,但这仍然意味着表单和视图中的大量工作。
这将首先为 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']
Run Code Online (Sandbox Code Playgroud)
必须为每个产品子类创建一个新表单。这看起来确实很简单,但产品模型会变得非常臃肿。
在这种情况下,我还可以使用代理模型。
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
Run Code Online (Sandbox Code Playgroud)
这种方法可以解决我遇到的 DRY 问题和上面的问题,但仍然不是最佳的。
无论如何,这是我想使用的方法,但更多的是能够向过于具体而无法放入产品或产品子类的产品添加“额外”功能。
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)
Run Code Online (Sandbox Code Playgroud)
这里的问题是这个方法是否应该用于所有产品属性,因为我认为这会增加数据库的大量开销。
这里的另一个挑战是值类型。在这种情况下,我只能使用字符值,那么当我想使用 Decimal 值或 File 时会发生什么?
可能有一些方法我目前还没有想到。所以,如果你知道一些我不知道的事情,请与我分享。
我在这里不是寻求任何意见,而是寻求一些解决方案。因此,如果您对这个问题有答案,请告诉我们您为什么要使用您建议的方法。