I have a django project which I want it to have phone number as its username field. I've created an app named accounts, and this is the models.py:
class UserManager(BaseUserManager):
use_in_migrations = True
def create_user(self, phone_number, password, **extra_fields):
user = self.model(phone_number=phone_number, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, phone_number, password, **extra_fields):
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
extra_fields.setdefault("is_active", 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_number, password, **extra_fields)
class User(AbstractUser):
phone_number = models.CharField(max_length=20, null=False, blank=False, unique=True)
email = models.EmailField(max_length=100, blank=True, null=True)
name = models.CharField(max_length=50)
USERNAME_FIELD = "phone_number"
username = None
first_name = None
last_name = None
objects = UserManager()
REQUIRED_FIELDS = [phone_number]
And I've declared it as my user model, in settings.py.
AUTH_USER_MODEL = "accounts.User"
ACCOUNT_USER_MODEL_USERNAME_FIELD = "phone_number"
When I run python manage.py createsuperuser
, I get this error:
django.core.exceptions.FieldDoesNotExist: User has no field named 'accounts.User.phone_number'
I can't figure out what is the problem.
This is the full error:
Traceback (most recent call last):
File "/home/foo/.local/lib/python3.10/site-packages/django/db/models/options.py", line 668, in get_field
return self.fields_map[field_name]
KeyError: <django.db.models.fields.CharField: phone_number>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/foo/Desktop/custom/manage.py", line 22, in <module>
main()
File "/home/foo/Desktop/custom/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/foo/.local/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
utility.execute()
File "/home/foo/.local/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/foo/.local/lib/python3.10/site-packages/django/core/management/base.py", line 394, in run_from_argv
parser = self.create_parser(argv[0], argv[1])
File "/home/foo/.local/lib/python3.10/site-packages/django/core/management/base.py", line 357, in create_parser
self.add_arguments(parser)
File "/home/foo/.local/lib/python3.10/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 61, in add_arguments
field = self.UserModel._meta.get_field(field_name)
File "/home/foo/.local/lib/python3.10/site-packages/django/db/models/options.py", line 670, in get_field
raise FieldDoesNotExist(
django.core.exceptions.FieldDoesNotExist: User has no field named 'accounts.User.phone_number'
CodePudding user response:
No need pass USERNAME FIELD in settings.py
you can pass explicitly USERNAME FIELD
like this...
class User(AbstractUser):
phone_number = models.CharField(max_length=20, null=False, blank=False, unique=True)
email = models.EmailField(max_length=100, blank=True, null=True)
name = models.CharField(max_length=50)
username = None
first_name = None
last_name = None
objects = UserManager()
USERNAME_FIELD = 'phone_number'
REQUIRED_FIELDS = [email]
for batter understanding refer this link here
CodePudding user response:
Its very easy my friend just add the following to the user model
USERNAME_FIELD = 'phone_number'
Look at this answer to know more: Django Login with Email or Phone Number
CodePudding user response:
There were three problems in my code:
- technically setting
username
field toNone
must be done before declaringUSERNAME_FIELD
. REQUIRED_FIELDS
itmes must be strings, not variables.phone_number
shouldn't be inREQUIRED_FIELDS
, as it'sUSERNAME_FIELD
.
So my User model class would be like this:
class User(AbstractUser):
username = None
first_name = None
last_name = None
phone_number = models.CharField(max_length=20, null=False, blank=False, unique=True)
email = models.EmailField(max_length=100, blank=True, null=True)
name = models.CharField(max_length=50)
USERNAME_FIELD = "phone_number"
objects = UserManager()
Update
As Mahammadhusain mentioned, there is no need to pass ACCOUNT_USER_MODEL_USERNAME_FIELD
in settings.py, as I've set USERNAME_FIELD
in models.py