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?
Related
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.
Good day SO.
I am new to Django and having troubles with something basic. What I am trying to do is when I click on register, I want to create an Account and at the same time, a company account.
When I click on sumbit, the template returns my Account(the OneToOneField) This field is required.
Though my methods might be not aligned with good practice, but I hope that you can help me with this. I have been trying to check with other resources for two days but I can't seem to find the solution to my concern.
Here is my forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from .models import Account, CompanyAccount
class AccountCreationForm(UserCreationForm):
email = forms.EmailField(max_length=60, help_text="Required")
class Meta:
model = Account
fields = ("email", "username", "password1", "password2", "account_type")
class CompanyAccountForm(forms.ModelForm):
class Meta:
model = CompanyAccount
fields = "__all__"
my models.py:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
# Create your models here.
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, account_type, password):
if not email:
raise ValueError("Users must have an Email Address")
if not username:
raise ValueError("Users must have an Username")
if not account_type:
raise ValueError("Users must have an Account Type")
user = self.model(
email=self.normalize_email(email),
username=username,
password=password,
account_type=account_type,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, account_type, password):
user = self.create_user(
email=self.normalize_email(email),
username=username,
password=password,
account_type=account_type,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name='Email', max_length=60, default='', null=False, unique=True)
username = models.CharField(verbose_name='Username', max_length=50, default='', null=False, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_joined = models.DateTimeField(verbose_name='last joined', auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
ACCOUNT_TYPE_CHOICES = (
(1, 'Applicant'),
(2, 'Company'),
(3, 'Client'),
)
account_type = models.PositiveSmallIntegerField(default=0, choices=ACCOUNT_TYPE_CHOICES)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'account_type', ]
objects = MyAccountManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
class CompanyAccount(models.Model):
account = models.OneToOneField(Account, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
company_name = models.CharField(max_length=100, default='', null=False)
views.py
context = {}
if request.method == "POST":
rForm = AccountCreationForm(request.POST)
cForm = CompanyAccountForm(request.POST)
if rForm.is_valid() and cForm.is_valid():
rForm.save()
cForm.save()
else:
rForm = AccountCreationForm()
context['rForm'] = rForm
cForm = CompanyAccountForm()
context['cForm'] = cForm
return render(request, 'registration/company_registration_form.html', context)
If you want your model's field to be allowed to be empty when submitting forms, add blank=True:
account = models.OneToOneField(Account, on_delete=models.CASCADE, blank=True)
https://docs.djangoproject.com/en/3.1/ref/models/fields/
I want add RegexField but i have this error. why?
found it on Google but there is nothing on regexfield
this is error
mob = models.RegexField(regex=r'^+?1?\d{9,15}$')
AttributeError: module 'django.db.models' has no attribute 'RegexField'
models.py
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django import forms
class UserManager(BaseUserManager):
"""Define a model manager for User model with no username field."""
use_in_migrations = True
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 given email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
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, **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)
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 User(AbstractUser):
"""User model."""
username = None
email = models.EmailField(_('email address'), unique=True)
mob = models.RegexField(regex=r'^\+?1?\d{9,15}$')
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
A RegexField [Django-doc] is a form field. You can use it in a form to validate text before you for example store it in a model, but not in a model.
What you can do is add a RegexValidator [Django-doc] as validator to your model field:
from django.core.validators import RegexValidator
class User(AbstractUser):
"""User model."""
username = None
email = models.EmailField(_('email address'), unique=True)
mob = models.CharField(
max_length=17,
validators=[RegexValidator(r'^\+?1?\d{9,15}$')]
)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
As of django-2.2 you can also make use of the constraint framework [Django-doc] to validate constraints at the database layer. Not all databases per se check constraints, so it is not guaranteed to validate it at the database layer. You can define a constraint with:
from django.db.models import Q
from django.core.validators import RegexValidator
class User(AbstractUser):
"""User model."""
username = None
email = models.EmailField(_('email address'), unique=True)
mob = models.CharField(
max_length=17,
validators=[RegexValidator(r'^\+?1?\d{9,15}$')]
)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
class Meta:
constraints = [
models.CheckConstraint(
check=Q(mob__regex=r'^\+?1?\d{9,15}$'),
name='mob_valid'
),
]
You can also define a form with RegexField, although if you add a validator that is not necessary. For example in a form you can add:
from django import forms
class UserForm(forms.ModelForm):
mob = forms.RegexField(regex=r'^\+?1?\d{9,15}$')
class Meta:
model = User
fields = '__all__'
In one of my models files in my Django project, I am trying to import AbstractBaseUser, and BaseUserManager from django.contrib.auth.base_user. I checked my site packages, and there is definitely a base_user python file in Django's auth directory, but I am getting this error when trying to make migrations.
ImportError: No module named base_user
If I was using the wrong Django version, it wouldn't show up in my site packages Django directory correct ? Also in Pycharm, my IDE, its not underlining it red with any errors.
models.py
from django.conf import settings
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.contrib.auth.hashers import get_hasher
from django.contrib.auth.models import PermissionsMixin
from django.db import models
from django.utils import timezone
from django.utils.text import slugify
class AccountUserManager(BaseUserManager):
# username is not used here, but is needed for facebook login to work correctly
def create_user(self, email, password=None, username=None, is_active=True):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
)
user.set_password(password)
user.last_login = timezone.now()
user.language_code = settings.LANGUAGE_CODE
user.is_active = is_active
user.save(using=self._db)
return user
def create_superuser(self, email, password):
user = self.create_user(email,
password=password,
)
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, max_length=255, verbose_name='Email',
help_text='Used for login and password recovery. Is also an account\'s display name if no Name is specified.')
first_name = models.CharField(max_length=100, blank=True, null=True, verbose_name='First Name',
help_text='User\'s first name.')
last_name = models.CharField(max_length=100, blank=True, null=True, verbose_name='Last Name',
help_text='User\'s last name.')
date_joined = models.DateTimeField(auto_now_add=True, verbose_name='Date Joined')
is_active = models.BooleanField(default=True, null=False, db_index=True, verbose_name='Is Active',
help_text='Uncheck to prevent user from being allowed to login.')
is_staff = models.BooleanField(default=False, null=False, verbose_name='Is Staff',
help_text='Grants administrator privileges.')
activation_key = models.CharField(max_length=40, blank=True, null=True)
key_expires = models.DateTimeField(blank=True, null=True)
objects = AccountUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
def get_full_name(self):
full_name = ''
if self.first_name is not None:
full_name += self.first_name
if self.last_name is not None:
full_name += ' ' + self.last_name
return full_name
# #property
def _full_name(self):
return self.get_full_name()
_full_name.short_description = 'Name'
full_name = property(_full_name)
def get_display_name(self):
if self.full_name.strip():
return self.full_name.rstrip()
return self.email.rstrip()
#property
def slug(self):
if self.full_name:
return slugify(self.full_name)
email_parts = self.email.split('#')
return slugify(email_parts[0])
def __unicode__(self):
return unicode(self.email)
class Meta:
verbose_name = 'User Account'
verbose_name_plural = 'User Accounts'
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