DJANGO - 将字段添加到默认的auth.User模型 - 最简单的方法

时间:2018-01-24 14:43:02

标签: python django django-users django-2.0

寻找向Django's User模型添加一个字段的最简单方法。

我有两种不同字段的用户 - 公司和客户,因此我决定创建两种类型的UserProfilesCompanyProfileCustomerProfile。每个用户都有CompanyProfileCustomerProfile

为了能够filter并决定使用哪种类型,我想将type字段添加到User模型。

你会建议什么?现在我在中间有UserProfile似乎有点矫枉过正,它使过滤,查找和许多其他事情变得不那么简单。

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='userprofile')
    type = models.CharField(max_length=100, choices=settings.OBSTARAJME_USERPROFILE_TYPE_CHOICES)
    company_profile = models.OneToOneField('CompanyProfile', null=True, blank=True, on_delete=models.CASCADE,
                                           related_name='userprofile')
    customer_profile = models.OneToOneField('CustomerProfile', null=True, blank=True, on_delete=models.CASCADE,
                                            related_name='userprofile')

我正考虑创建自定义User 模型。

class User(AbstractBaseUser):
    type = models.CharField(max_length=100, choices=settings.OBSTARAJME_USER_TYPE_CHOICES)
    USERNAME_FIELD = 'username'

Django表示没有像username这样的字段,我希望避免手动编写整个User模型及其所有字段。

修改 我知道我可以根据customerprofile__isnull=False进行过滤,所以实际上我根本不需要type字段,但它看起来不是最好的方法。

1 个答案:

答案 0 :(得分:0)

您的上一次编辑实际上提供了最简单的解决方案:不要添加type和中间模型。如果User在某个阶段同时成为CompanyCustomer(即使这不是您现在所期望的,业务需求会发生变化......),该怎么办? type无法做到这一点。

所以:只需使用User模型中的ForeignKeyOneToOneField指向Profile,并且不要向User添加任何内容。

如何使代码更简单,可以添加UserManager以提高查询的可读性:

class UserManager(DefaultUserManager):

    def companies(self):
        return self.get_queryset().filter(customerprofile__isnull=False)

通过这种方式,您可以执行contract.parties.companies()之类的查询(假设contract有多个parties,这些UserUserManager个对象的查询集。

使用AbstractUser,您还需要子类objects来覆盖默认的Set设置。