Python-创建多个用户类型,并在Django 2中作为用户名字段发送电子邮件

问题描述 投票:1回答:2

我正在使用Python(3.7)和Django(2.2)开发一个项目,在其中我必须以以下方式实现多种类型的用户:

  1. 个人帐户-18岁以下
  2. 个人帐户-18岁以上
  3. 父母帐户
  4. 教练帐户
  5. 管理员

此外,我还需要使用email作为登录/身份验证的username字段。

[我正在尝试使用的策略是构建一个自User继承的AbstractBaseUser的自定义基本模型,并且还创建了一个自定义User Manager以使email成为username,但它不起作用。] >

这是我完整的模型代码:

class UserManager(BaseUserManager):

    def _create_user(self, email, password, is_staff, is_superuser, **extra_fields):
        if not email:
            raise ValueError('Users must have an email address')
        now = timezone.now()
        email = self.normalize_email(email)
        user = self.model(
            email=email,
            is_staff=is_staff,
            is_active=True,
            is_superuser=is_superuser,
            last_login=now,
            date_joined=now,
            **extra_fields
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email=None, password=None, **extra_fields):
        return self._create_user(email, password, False, False, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        user = self._create_user(email, password, True, True, **extra_fields)
        user.save(using=self._db)
        return user


def generate_cid():
    customer_number = "".join([random.choice(string.digits) for i in range(10)])
    return customer_number


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=255, unique=True)
    is_personal_above_18 = models.BooleanField(default=False)
    is_personal_below_18 = models.BooleanField(default=False)
    is_parent = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)

    USERNAME_FIELD = 'email'
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

    def get_absolute_url(self):
        return "/users/%i/" % self.pk

    def get_email(self):
        return self.email


class PersonalAccountAbove18(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE,
                                primary_key=True, related_name='profile')
    customer_id = models.BigIntegerField(default=generate_cid)


class PersonalAccountBelow18(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE,
                                primary_key=True, related_name='profile')
    customer_id = models.BigIntegerField(blank=False)


class ParentAccount(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE,
                                primary_key=True, related_name='profile')
    customer_id = models.BigIntegerField(default=generate_cid)

我对我的方法感到困惑,甚至当我以makemigrations身份运行时,它也返回错误:

users.User.user_permissions :(字段E304)“ User.user_permissions”的反向访问器与“ User.user_permissions”的反向访问器冲突。提示:在“ User.user_permissions”或“ User.user_permissions”的定义中添加或更改related_name参数。

更新:

我从子模型中删除了PermissionMixinrelated_name属性,并且迁移现在正在运行,但仍需要username而不是email

[我正在使用Python(3.7)和Django(2.2)开发一个项目,在该项目中,我必须实现多种类型的用户:个人帐户-18岁以下的个人帐户-18岁以上的父母帐户的教练...

python django python-3.x django-models django-2.0
2个回答
0
投票

对于使用电子邮件作为登录名,我建议使用django-allauth软件包。它可以解决所有繁重的工作,您可以使用它通过电子邮件(而不是用户名)登录。文森特(Will Vincent)对此有撰写,请访问:

https://wsvincent.com/django-allauth-tutorial-custom-user-model/


0
投票

makemigrations中的错误以及以后(除去PermissionsMixin之后)要求使用username而非email进行身份验证的提示是,您尚未将自定义模型设置为default

© www.soinside.com 2019 - 2024. All rights reserved.