python定义用户类user,Python-在Django 2中创建多种用户类型并将电子邮件作为用户名字段...

I'm working on a project using Python(3.7) and Django(2.2) in which I have to implement multiple types of users as:

Personal Account - below 18

Personal Account - above 18

Parent Account

Coach Account

Admin

along with that, I also need to use email as the username field for login/authentication.

The strategy I'm trying to use is to build a custom base model as User inherited from AbstractBaseUser and also created a custom User Manager to make the email as username but it's not working.

Here's my complete model code:

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)

I'm confused about my approach and even it's also return an error when I run makemigrations as:

users.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'User.user_permissions'.

HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'User.user_permissions'.

Update:

I removed the PermissionMixin and related_name attributes from child models and migrations are running now but it still require the username instead of email.

解决方案

The errors in makemigrations, and later (after dropping PermissionsMixin) requiring username instead of email for authentication are hints that you have not set your custom model as the default user model to be used by the Django auth app. As a result, Django is using the auth.User model as the default user model and your one being added to the project like any other model. So both of the user models exist simultaneously with the auth.User being the default/active one used for authentication purposes.

In essence, edit your settings.py to add the following:

AUTH_USER_MODEL = '.User'

Now Django will use your customized User model instead of the one from auth app (the default) and the auth.User model will be dropped. The auth app uses the get_user_model (django.contrib.auth.get_user_model) function to get the currently active user model for the project which checks for settings.AUTH_USER_MODEL, and by default the rest of the system (e.g. the admin app) also checks for this setting to get the current user model. So as long as you're using the auth app the above should suffice.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值