问题描述
情况:
我们拥有一个现有系统,当前员工可以使用其手机号码登录该系统。
但是由于相同的手机号码可以由多个用户使用,因此现有数据库中存在一个限制,即在任何时候,只有一个用户可以使用给定的“手机号码”和“ 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 =''。现在设置为手机。