Django多外键Mod

2024-10-16 20:42:56 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的代码,有没有更有效的方法来编写它? 我对此不感冒。在

基本上,公司和供应商的模型都应该是abble,有几个联系人和几个电话号码。在

class Contact(models.Model):
    company = models.ForeignKey(Company, related_name='contact',
        blank=True, null=True)
    supplier = models.ForeignKey(Supplier, related_name='contact',
        blank=True, null=True)
    name = models.CharFields(max_length=50, blank=True, null=True)
class Phone(models.Model):
    contact = models.ForeignKey(Contato, related_name='phone')
    number = models.CharFields(max_length=50, blank=True, null=True)

Tags: 方法代码nametruemodelmodelscontactnull
2条回答

对我来说Company和{}模型可能是相同的。既然大多数供应商都是公司对吗?如果它们基本上与合并CompanySupplier模型相同,则:

class Company(models.Model):
    name = models.CharFields(max_length=50)
    is_supplier = models.BooleanField(default=False)  
    suppliers = models.ManyToManyField("self", 
        limit_choices_to={'is_supplier': True})


class Contact(models.Model):
    name = models.CharFields(max_length=50)    
    company = models.ForeignKey(Company)


class Phone(models.Model):
    number = models.CharFields(max_length=50)    
    contact = models.ForeignKey(Contact)

这是克里斯·德罗斯的“两桌”解决方案。如果您需要特定于供应商的字段,而不是添加供应商模型并使用OneToOne将其链接到公司:

^{pr2}$

对于“X型公司和Y型公司都有联系人”问题,至少有四种方法:

  1. 两张表:公司和联系人。公司有一个枚举属性,其值为X和Y,并且每个联系人都有一个公司的外键。在
  2. 三个表:一个表X用于X公司,另一个表Y用于Y公司,一个表用于联系人C,其中C同时具有X和Y的外键。外键可以为空。在
  3. 四个表:X、Y、Cx和Cy,分别跟踪两个不同类型公司的两个不同联系人。(所以Cx有X的外键,Cy有Y的外键)。在
  4. 五个表:从这三个表X、Y和C开始,但是没有向C添加可为null的指针,而是添加两个多对多连接表XC和YC。在

它们对底层数据有不同的要求。您现在使用的是三表解决方案(X, Y, C) = (Company, Supplier, Contact)。如果一些联系人将在公司和供应商之间共享,这样您有时需要问“谁是这家公司和那个供应商之间的联系人?”。我维护一个使用双表解决方案的数据库,当它最初被采用时,它是一个很好的解决方案(为什么我们不必重复地址和联系人的逻辑?)但今天它看起来很笨拙(因为“Company”表包含的字段只对X和Y单独有意义)。在

在我的例子中,如果我们迁移的话,最容易处理的可能是四表解决方案:将X型公司的联系人与Y型公司的联系人完全分开。如果您从当前的方法开始,那么如果您在应用程序中面临类似的成长难题,那么五表解决方案将是明显的概括。在

至于追踪电话号码,你有一些有限的选择:

  1. 在Contacts表中存储一组列,每个单独的电话号码对应一列。这真的很快就变丑了,但这是一个快速简单的方法。这称为“非规范化”数据。在
  2. 将JSON存储在联系人列表的文本字段中。电话号码不太可能被搜索太多;只是说“我有这个号码,它是谁的”并不常见,因此可以轻松地反规范化。这还允许您执行{"mon thru thurs": 12025551234, "fri, sat": 12025554321}之类的操作,为数字存储简单的自定义注释。在
  3. 创建一个电话表,就像你现在所做的那样。这是最常用的方法,如果需要这些类型的注释,可以向该表添加另一个文本字段。在

如果您将选项3与上面的选项3混合使用(四个表加上一个显式电话表),那么您可能希望有单独的电话表和单独的联系人表;Px和Py各有一个Cx和Cy的外键

相关问题 更多 >