多对多或一对多Django

时间:2016-12-31 19:06:18

标签: python django django-models models

我在Django中有以下两个模型。一个基本上是基本Django用户类的扩展,另一个是公司模型。我想说一个用户可以属于一个或多个公司,公司也可以有一个或多个联系人=“用户”。这是一个正确的设置吗?我应该如何表示用户与公司之间的联系?

用户个人资料模型:

class Profile(models.Model):
    user = models.OneToOneField(User)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

公司型号:

class Company(models.Model):
    name = models.CharField(max_length=120)
    account_name = models.CharField(max_length=10, default="")
    sales_rep = models.ForeignKey(User, related_name="%(app_label)s_%(class)s_sales", default="")
    csr = models.ForeignKey(User, related_name="%(app_label)s_%(class)s_csr", default="")

class CompanyContact(models.Model):
    name = models.CharField(max_length=40, default="")
    email = models.CharField(max_length=50, default="")
    user = models.ForeignKey(User)
    company = models.ForeignKey(Company)

1 个答案:

答案 0 :(得分:3)

首先,是否有理由扩展User模型?默认模型已包含first_namelast_name字段,因此您不需要仅针对该数据的其他模型。同样,您实际上并不需要CompanyContact,因为User模型还包含emailname(再次通过first_namelast_name)字段。

您可以将自己的联系人添加为ManyToManyField。如果您想使用自定义Profile模型而不是User,只需将UserManyToManyField)替换为Profile

class Company(models.Model):
    name = models.CharField(max_length=120)
    account_name = models.CharField(max_length=10, default="")
    sales_rep = models.ForeignKey(User, related_name="%(app_label)s_%(class)s_sales", default="")
    csr = models.ForeignKey(User, related_name="%(app_label)s_%(class)s_csr", default="")
    contacts = models.ManyToManyField(User) # or Profile

这允许每家公司拥有许多联系人,并且每个用户都是许多公司的联系人 - 因此多对多。

现在,如果您想要额外的数据来描述多对多关系,you can have another model for that。例如,如果联系人仍处于活动状态或他们的角色是什么,您可能希望保留记录。因此,您可能有CompanyContact模型,类似于:

class CompanyContact(models.Model):
    active = models.BooleanField(default=False)
    role = models.CharField(max_length=50, default="")
    user = models.ForeignKey(User) # or Profile
    company = models.ForeignKey(Company)

然后,声明ManyToManyField关系以使用此新模型:

class Company(models.Model):
    ...
    contacts = models.ManyToManyField(User, through="CompanyContact")
    # or contacts = models.ManyToManyField(Profile, through="CompanyContact")