首页 > 解决方案 > Django:为自定义用户模型使用外键关系

问题描述

我正在编写一个 web 应用程序,我希望有一个通用Person表来唯一标识与网站交互的任何人,例如能够遵守 GDPR 请求。

有些Persons will 也应该是User身份验证意义上的 s。我想Person.email用于用户名。

但是,我无法使身份验证/管理界面正常工作。

简化模型:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin


class Person(models.Model):
    name = models.CharField(max_length=255, blank=False)
    email = models.EmailField(blank=False, unique=True)

class User(AbstractBaseUser, PermissionsMixin):
    person = models.OneToOneField(Person, on_delete=models.PROTECT)

    USERNAME_FIELD = ...# what to put here?

我发现了一个似乎相关的非常古老的 Django 问题: https ://code.djangoproject.com/ticket/21832

任何想法,如何使用外键来保存基本用户信息?

标签: pythondjangodjango-modelsdjango-authentication

解决方案


从 django.db 导入模型 从 django.contrib.auth.models 导入 AbstractBaseUser, PermissionsMixin

在这里,您可以找到实现这一目标的正确方法

class User(AbstractBaseUser, PermissionsMixin):
   email = models.EmailField(unique=True)

    USERNAME_FIELD = ['email']  # It's mean you can login with your email

class Person(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

注意:如果您使用AbstractBaseUser模型,那么您必须编写自定义模型管理器。

为避免编写自定义模型管理器,您应该使用AbstractUser

class User(AbstractUser):
      pass
      # here all the required fields like email, name etc item

当用户使用 django 信号创建记录时,您可以Person为用户创建记录:

https://docs.djangoproject.com/en/3.2/topics/signals/


推荐阅读