我目前正在为客户构建一个应用程序,其中每个记录都有大量不同的信息(大约50-60个字段)。
我想将模型分解为多个部分,以便数据更加结构化。
我的第一次尝试是做这样的事情:
class Program(models.Model):
class BookingInformation(models.Model):
program = models.OneToOneField('Program', related_name='booking_information')
producer = models.CharField(max_length=100, blank=True)
producer_phone = models.CharField(max_length=30, blank=True)
...
class Editorial(models.Model):
program = models.OneToOneField('Program')
series = models.CharField(max_length=100, blank=True)
...
我有5个左右的部分,其中一些是嵌套的。
通过这种方式,我可以拥有一个程序对象并执行program.booking_information.producer
来获取该字段。此外,我可以更轻松地使用ModelForm
为每个部分(我喜欢的部分)提供单独的表单。
创建对象时出现了困难。因为当我创建一个Program对象时,Program.BookingInformation对象还不存在,如果没有先保存该程序,我就无法实现它(因此它获得了一个主键)。然后,当他们不是绝对必要的时候,我会阅读像this which appear to discourage the use of OneToOneFields这样的内容。
我应该将整批产品放入一个型号吗?拥有一个包含所有这些字段的大表对我来说似乎很麻烦,但后来我对这个数据库的东西很新。
答案 0 :(得分:1)
在数据库级别上,对于与单个模型一对一的数据使用单独的表是个坏主意。在这些单独的表中查询将需要两倍的查询量,从而减慢了应用程序的速度并使这些模型的使用变得复杂。一般来说,你不应该尽可能少的查询。
可能的做法是将不同的“数据组”数据划分为您继承的单独抽象模型:
class BookingInformation(models.Model):
# fields
class Meta:
abstract = True
class Program(BookingInformation, Editorial, etc.):
pass
它可能会使您的代码更具可读性,但我并没有真正看到它的明显优势,如果您在模型中需要更多高级逻辑,则可能会遇到问题。我建议你把所有内容都放在一个单独的类中,用空白行和注释等对这些组进行视觉区分。
要获取所需的单独表单,您可以指定多个ModelForm
个类,每个类都定义了自己的fields
选项:
class BookingInformationForm(forms.ModelForm):
class Meta:
fields = ['producer', 'producer_phone', etc]
这将要求模型的大多数(如果不是全部)字段具有null=True
或blank=True
,具体取决于特定字段,以防止在创建具有仅具有模型字段的子集。