Cannot input username into Custom super user Django - python

I want to create a custom authentication for Django. Created a custom class and manager as well. I'm not able to run the command python manage.py createsuperuser with --username attribute. It says there's not parameter like that.
Without username it gives a value error of null Username. Please help.
This is my models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import BaseUserManager
class AccountManager(BaseUserManager):
def create_user(self, email, password=None, **kwargs):
if not email:
raise ValueError('Users must have a valid email address')
if not kwargs.get('username'):
raise ValueError('Users must have a valid username')
account = self.model(
email=self.normalize_email(email), username=kwargs.get('username')
)
account.set_password(password)
account.save()
return account
def create_superuser(self, email, password, **kwargs):
account = self.create_user(email, password, **kwargs)
account.is_admin = True
account.save()
return account
class Account(AbstractBaseUser):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True)
first_name = models.CharField(max_length=40, blank=True)
last_name = models.CharField(max_length=40, blank=True)
tagline = models.CharField(max_length=150, blank=True)
is_admin = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FILEDS = ['username']
def __unicode__(self):
return self.email
def get_full_name(self):
return ''.join([self.first_name, self.last_name])
def get_short_name(self):
return self.first_name

Related

Django: Custom User Model with Autoincrementing Id

I am trying to use Django Authentication and I want to create a custom model for the user that has an autoincrementing integer as id. I know about uuid library, but I want the id to be an integer number, that is why I want to avoid it.
My code looks like:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyAccountManager(BaseUserManager):
def create_user(self, first_name, last_name, email, username, avatar, password=None):
if not username:
raise ValueError('User must have an username')
if not avatar:
raise ValueError('User must have an avatar')
user = self.model(
email=self.normalize_email(email),
username=username,
avatar=avatar,
first_name=first_name,
last_name=last_name
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, first_name, last_name, email, username, avatar, password):
user = self.create_user(
email=self.normalize_email(email),
username=username,
avatar=avatar,
password=password,
first_name=first_name,
last_name=last_name
)
user.is_admin = True
user.is_active = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
id = models.AutoField(primary_key=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
username = models.CharField(max_length=50, unique=True)
email = models.CharField(max_length=50, unique=True)
avatar = models.CharField(max_length=200)
# required
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_superadmin = models.BooleanField(default=False)
USERNAME_FIELD = 'id'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name', 'email', 'avatar']
objects = MyAccountManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, add_label):
return True
The problem is that I still want to log in with the username, not the id. Also, as it autoincrements, it would be nice that I won't have to manually introduce it when I create a superuser from the console.
Is this possible?
I tried to solve your requirement... using save method overriding
Model code:
class CustomUserModel(AbstractBaseUser, PermissionsMixin):
auto_id = models.PositiveBigIntegerField(unique=True)
username = models.CharField(max_length=255, unique=True)
email = models.EmailField(verbose_name="email address", max_length=255, unique=True)
mobile_no = models.PositiveIntegerField(verbose_name="mobile number",unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
objects = CustomUserManager()
USERNAME_FIELD = "username"
REQUIRED_FIELDS = ['email','mobile_no']
def save(self, *args, **kwargs):
count_id = CustomUserModel.objects.all().count()
self.auto_id = count_id+1
super(CustomUserModel, self).save(*args, **kwargs)
def __str__(self):
return self.email
Output admin panel view:

IntegrityError FOREIGN KEY constraint failed - Django custom user model

After creating a custom user model in Django and trying to edit a user in Django admin i get an IntegrityError.
I get a IntegrityError at /admin/accounts/customuser/add/ FOREIGN KEY constraint failed when I delete a user in Django admin. This also happens when I try to add a user in Django admin.
Code
models.py
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import gettext_lazy as _
class UserManager(BaseUserManager):
def _create_user(self, email, password, **kwargs):
if not email:
raise ValueError("Email is required")
email = self.normalize_email(email)
user = self.model(email=email, **kwargs)
user.set_password(password)
user.save()
return user
def create_user(self, email, password=None, **extra_fields):
"""Create and save a regular User with the given email and password."""
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **kwargs):
kwargs.setdefault('is_staff', True)
kwargs.setdefault('is_superuser', True)
kwargs.setdefault('is_active', True)
if kwargs.get('is_staff') is not True:
raise ValueError("Superuser must have is_staff True")
if kwargs.get('is_superuser') is not True:
raise ValueError("Superuser must have is_superuser True")
return self._create_user(email, password, **kwargs)
class CustomUser(AbstractUser):
username = None
first_name = None
last_name = None
email = models.EmailField(_('email address'), blank=False, null=False, unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
full_name = models.CharField(_('full name'), max_length=1000, null=True, blank=True)
user_id = models.CharField(_('session id'), max_length=10000, null=True, blank=True)
verification_code_time = models.IntegerField(_('time left for session id'), null=True, blank=True)
verification_code = models.IntegerField(_('verification code'), null=True, blank=True)
objects = UserManager()
def __str__(self):
return self.email
admin.py
from django.contrib import admin
from .models import CustomUser
admin.site.register(CustomUser)
Any suggestions?

OperationalError at /admin/auctions/listings/ no such column: auctions_listings.category_id

I'm trying to create categories for my listings but it shows the above error.
I also tried adding the id column manually but then it shows this error:
AssertionError: Model auctions.Category can't have more than one auto-generated field.
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser,BaseUserManager
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
# Create your models here.
class myUserManager(BaseUserManager):
"""
custom user model manager where email is unique indentifiers for authenticaton
instead of usernames.
"""
def create_user(self, email, password, **extra_fields):
"""
Create and save a User with the given email and password.
"""
if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
"""
Create and save a SuperUser with the given email and password.
"""
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(email,password, **extra_fields)
class myUser(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = myUserManager()
def __str__(self):
return f'{self.email}'
class Category(models.Model):
category = models.CharField(max_length=50, default="No Category")
def __str__(self):
return f'{self.category}'
class Listings(models.Model):
listing_name = models.CharField(max_length=50)
price = models.IntegerField(default=1)
date_listed = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
category = models.ForeignKey(Category,on_delete=models.DO_NOTHING,null=True,blank=True)
item_image = models.ImageField()
description = models.TextField(max_length=200, default="Description Not Available")
listed_by = models.ForeignKey(myUser,on_delete=models.CASCADE, default=1,null=True)
def __str__(self):
return f'{self.listing_name}'
class Bid(models.Model):
item_name = models.ForeignKey(Listings,on_delete=models.CASCADE)
bid_by_user = models.ForeignKey(myUser,on_delete=models.CASCADE)
new_bid = models.IntegerField()
Please tell me what to do and if there is any better way to do it please do tell me I'd really appreciate it.

TypeError: create_superuser() missing 1 required positional argument: 'profile_picture'

I get the following error after adding the profile_picture field:
TypeError: create_superuser() missing 1 required positional argument: 'profile_picture'
This profile_picture field is an "ImageField" set as "Null = True".
I have tried the following: def create_user(...., profile_picture=None, ....). It didn't work.
and the error occurs only in command prompt when i create superuser from there.
Here is my models.py
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
class UserManager(BaseUserManager):
def create_user(self, email, full_name, profile_picture=None, gender=None, password=None, is_admin=False, is_staff=False, is_active=True):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
if not full_name:
raise ValueError("User must have a full name")
user = self.model(
email=self.normalize_email(email)
)
user.full_name = full_name
user.set_password(password) # change password to hash
# user.profile_picture = profile_picture
user.gender = gender
user.admin = is_admin
user.profile_picture = profile_picture
user.staff = is_staff
user.active = is_active
user.save(using=self._db)
return user
def create_staffuser(self, email, profile_picture, gender, full_name, password=None):
user = self.create_user(
email,
full_name,
profile_picture,
gender,
password=password,
is_staff=True,
)
return user
def create_superuser(self, email, profile_picture, gender, full_name, password=None):
user = self.create_user(
email,
full_name,
profile_picture,
gender,
password=password,
is_staff=True,
is_admin=True,
)
return user
class User(AbstractBaseUser):
username = models.CharField(max_length=255)
full_name = models.CharField(max_length=255)
email = models.EmailField(max_length=255, unique=True,)
profile_picture = models.ImageField(upload_to='user_data/profile_picture', null=True, blank=True)
gender = models.CharField(max_length=255, blank=True, default='rather_not_say')
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser
# notice the absence of a "Password field", that's built in.
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['full_name', 'gender'] # Email & Password are required by default.
objects = UserManager()
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
#staticmethod
def has_perm(perm, obj=None):
# "Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
#staticmethod
def has_module_perms(app_label):
# "Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
# "Is the user a member of staff?"
return self.staff
#property
def is_admin(self):
# "Is the user a admin member?"
return self.admin
#property
def is_active(self):
# "Is the user active?"
return self.active
You can add username to the REQUIRED_FIELDS. After that python manage.py createsuperuser asks for username field and it works.
REQUIRED_FIELDS = ['full_name', 'gender', 'username',]
Well, you need to create the create_superuser function as well:
class UserManager(BaseUserManager):
def create_user(self, email, full_name, profile_picture, password=None, is_admin=False, is_staff=False, is_active=True):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
if not full_name:
raise ValueError("User must have a full name")
user = self.model(
email=self.normalize_email(email)
)
user.full_name = full_name
user.set_password(password) # change password to hash
user.profile_picture = profile_picture
user.admin = is_admin
user.staff = is_staff
user.active = is_active
user.save(using=self._db)
return user
def create_superuser(self, email, full_name, profile_picture, password=None, **extra_fields):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
if not full_name:
raise ValueError("User must have a full name")
user = self.model(
email=self.normalize_email(email)
)
user.full_name = full_name
user.set_password(password)
user.profile_picture = profile_picture
user.admin = True
user.staff = True
user.active = True
user.save(using=self._db)
return user
Good Luck!
I had the same problem, it turned out that in the list named REQUIRED_FIELDS was misnamed.
That list tells the django framework to ask for name as well during the creation. Because it is not asking and you've made it necessary.
I hope it helps, best of luck
i solved this problem with some changes
my old code
class User(AbstractUser):
username = None
name = models.CharField(max_length=200, null=True)
email = models.EmailField(unique=True, null=True)
bio = models.TextField(null=True)
avatar = models.ImageField(null=True, default="avatar.svg")
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
and i edited username field to email field
class User(AbstractUser):
username = models.EmailField(unique=True, null=True)
name = models.CharField(max_length=200, null=True)
bio = models.TextField(null=True)
avatar = models.ImageField(null=True, default="avatar.svg")
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = []
Conculation
username = None => username = models.EmailField(unique=True, null=True)
Happy coding :)
Better to create a class in 0001.initial.py file of migrations. Define a class with all required fields for login and provide dependencies and operations blocks empty.That's it
Make a 0001_initial.py file inside the migrations folder and follow up the below code it will work...
from django.db import migrations
from api.user.models import CustomUser
class Migration(migrations.Migration):
def seed_data(apps, schema_editor):
user = CustomUser(name='name',
email='mail#gmail.com',
is_staff=True,
is_superuser=True,
phone='987654321',
gender='Male'
)
user.set_password('anypassword')
user.save()
dependencies=[
]
operations=[
migrations.RunPython(seed_data),
]
You need to add "profile_picture" to "REQUIRED_FIELDS" in the class "User(AbstractBaseUser)" in "models.py":
# "models.py"
class User(AbstractBaseUser):
# ... # Here
REQUIRED_FIELDS = ['full_name', 'profile_picture', 'gender']
# ...
You need to add profile_picture to REQUIRED_FIELDS in the class User(AbstractBaseUser) in models.py:

Django not updating SQLite tables properly

I've been working on a project that involves an authentication page using Django and AngularJS. I have created an extended version of the User class and have added "company" and "phone_number" as fields.
Here's my code for models.py:
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
from django.core.validators import RegexValidator
class AccountManager(BaseUserManager):
def create_user(self, email, password=None, **kwargs):
if not email:
raise ValueError('Users must have a valid email address')
#if not kwargs.get('username'):
#raise ValueError('Users must have a valid username')
#if access_code not in ['password']:
#raise ValueError('Sorry you are not eligible to join')
account = self.model(
email=self.normalize_email(email))
account.set_password(password)
account.save()
return account
def create_superuser(self, email, password, **kwargs):
account = self.create_user(email, password, **kwargs)
account.is_admin = True
account.save()
return account
class Account(AbstractBaseUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=40, blank=False)
last_name = models.CharField(max_length=40, blank=False)
company = models.CharField(max_length=40, blank=False)
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
phone_number = models.IntegerField(validators=[phone_regex], blank=False, null=True) # validators should be a list
# access_code = models.CharField(max_length=40, blank=False, default='SOME STRING')
is_admin = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'company', 'phone_number']
def __unicode__(self):
return self.email
def get_full_name(self):
return ' '.join([self.first_name, self.last_name])
def get_short_name(self):
return self.first_name
Now when I go to terminal and perform python manage.py createsuperuser all the field options pop up for me to enter text. However when I check the database afterwards, only the email and password fields are updated. Company, phone number, first name, and last name return as ' '.
Any clue what I am doing wrong? I've been spending too much time trying to fix this problem.
Thanks
In create_user, you haven't passed any of the other arguments to the self.model call, so you only set the email and, later, the password. You need to pass the kwargs in there too.
account = self.model(email=self.normalize_email(email), **kwargs)

Categories

Resources