微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Django中具有“ USERNAME_FIELD”唯一身份的自定义用户

如何解决在Django中具有“ USERNAME_FIELD”唯一身份的自定义用户

情况:
我们拥有一个现有系统,当前员工可以使用其手机号码登录该系统。
但是由于相同的手机号码可以由多个用户使用,因此现有数据库中存在一个限制,即在任何时候,只有一个用户可以使用给定的“手机号码”和“ is_active:真”(即他们可能是其他已注册员工)相同的数字,但离开时其状态为“ is_active”将变为“ false”。
另外,只有管理员才能添加/注册新员工/用户
我创建了一个自定义用户”模型和“ UserManager”,如下所示:

models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import gettext_lazy as _
from .managers import UserManager


# Create your models here.
class User(AbstractBaseUser,PermissionsMixin):
    """
    A class implementing a fully featured User model.
    Phone number is required. Other fields are optional.
    """
    first_name = models.CharField(_('first name'),max_length=50,null=True,blank=True)
    last_name = models.CharField(_('last name'),blank=True)
    phone = models.CharField(
        _('phone number'),max_length=10,null=False,blank=False,help_text=_('Must be of 10 digits only')
        )
    email = models.EmailField(_('email address'),blank=True)
    is_staff = models.BooleanField(
        _('staff status'),default=False,help_text=_('Designates whether the user is a staff member.'),)
    is_active = models.BooleanField(
        _('active'),default=True,help_text=_(
            'Designates whether this user should be treated as active.'
            'Unselect this instead of deleting accounts.'
        ),)
    date_joined = models.DateTimeField(_('date joined'),auto_Now_add=True)
    last_updated = models.DateTimeField(_('last updated'),auto_Now=True)

    objects = UserManager()

    USERNAME_FIELD = 'phone'
    required_FIELDS = []

    def get_full_name(self):
        """
        Return the first_name plus the last_name,with a space in between.
        """
        return self.first_name + ' ' + self.last_name

    def get_short_name(self):
        """Return the short name for the user."""
        return self.first_name

    # def email_user(self,subject,message,from_email=None,**kwargs):
    #     """Send an email to this user."""
    #     send_mail(subject,from_email,[self.email],**kwargs)

    # def sms_user(self,from=None,**kwargs):
    #     """Send a sms to this user."""
    #     send_sms(subject,from,[self.phone],**kwargs)

    def __str__(self):
        return self.first_name + ' ' + self.last_name

managers.py

from django.contrib.auth.models import BaseUserManager


# Create your models here.
class UserManager(BaseUserManager):
    """Define a model manager for User model"""

    use_in_migrations = True

    def normalize_phone(self,phone):
        """
        Applies NFKC Unicode normalization to usernames so that visually identical
        characters with different Unicode code points are considered identical
        """
        phone = self.model.normalize_username(phone)
        phone = phone.strip()
        if not phone.isdigit() or len(phone) != 10:
            raise ValueError('Phone number must of 10 digits only')
        return phone

    def make_default_password(self,phone):
        """
        Generates a default password
        by concatenating Digi + Phone number
        """
        return 'Pass' + phone

    def _create_user(self,phone,password=None,**extra_fields):
        """Create and save a User in DB with the given phone"""
        if not phone:
            raise ValueError('Phone number must be provided')
        phone = self.normalize_phone(phone)
        password = self.make_default_password(phone)
        user = self.model(phone=phone,**extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self,**extra_fields):
        """Create and save a regular User with the given phone and password"""
        extra_fields.setdefault('is_staff',False)
        extra_fields.setdefault('is_superuser',False)
        return self._create_user(phone,password,**extra_fields)

    def create_staff(self,True)
        extra_fields.setdefault('is_superuser',**extra_fields)

    def create_superuser(self,**extra_fields):
        """Create and save a Superuser with the given phone and password"""
        extra_fields.setdefault('is_staff',True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True')
        return self._create_user(phone,**extra_fields)

现在,当我运行python manage.py makemigrations时,出现以下错误

users.User: (auth.E003) 'User.phone' must be unique because it is named as the 'USERNAME_FIELD'

我被困住了,下一步该怎么做。
与以上查询或建议有关在上述情况下如何进行的任何帮助将不胜感激。
我是Django的新手,并尝试使用DjangoRestFramework重写Django中其余的后端。

解决方法

在用户模型的电话字段上添加unique = False。

phone = models.CharField(
        _('phone number'),max_length=10,unique=False
        null=False,blank=False,help_text=_('Must be of 10 digits only')
        )

或者您可以使用另一个字段作为USERNAME_FIELD =''。现在设置为手机。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。