Reputation: 865
I have the following custom user model implementation in my Django application :
users/models.py
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, email: str,
password: str, is_staff: bool,
is_superuser: bool, **extra_fields):
"""Creates and saves a User with the given email and password.
"""
email = self.normalize_email(email)
user = self.model(email=email, is_staff=is_staff, is_active=True,
is_superuser=is_superuser, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email: str, password=None, **extra_fields):
return self._create_user(email, password, False, False, **extra_fields)
def create_superuser(self, email: str, password: str, **extra_fields):
return self._create_user(email, password, True, True, **extra_fields)
class User(AbstractUser, UUIDModel):
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
email = models.EmailField(unique=True, db_index=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
objects = UserManager()
class Meta:
verbose_name = 'user'
verbose_name_plural = 'users'
ordering = ('-date_joined', )
def get_full_name(self):
return "{} {}".format(self.first_name, self.last_name)
def get_short_name(self):
return self.first_name
def get_email(self):
return self.email
def __str__(self):
return "{}".format(self.email)
And my change form in admin.py looks like this :
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as AuthUserAdmin
from django.contrib.auth.forms import UserChangeForm as DjangoUserChangeForm
from django.contrib.auth.forms import UserCreationForm as DjangoUserCreationForm
from .models import User
# Forms
# ----------------------------------------------------------------------------
class MyUserCreationForm(DjangoUserCreationForm):
class Meta:
model = User
fields = ("email",)
class MyUserChangeForm(DjangoUserChangeForm):
class Meta:
model = User
fields = '__all__'
# ModelAdmins
# ----------------------------------------------------------------------------
@admin.register(User)
class UserAdmin(AuthUserAdmin):
add_form_template = 'admin/auth/user/add_form.html'
model = User
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('first_name', 'last_name',)}),
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
('Important dates', {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2'),
}),
)
readonly_fields = ('date_joined', 'last_login')
form = MyUserChangeForm
add_form = MyUserCreationForm
list_display = ('email', 'first_name', 'last_name', 'is_active')
list_filter = ('is_superuser', 'is_active')
search_fields = ('first_name', 'last_name', 'email')
ordering = ('email',)
I have added these two lines in my settings.py
files.
AUTH_USER_MODEL = 'users.User'
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",)
I have extended this model to a custom profile model. But when I try to create another user I get the following error django.db.utils.IntegrityError: (1062, "Duplicate entry '' for key 'username'")
. Can anybody help me with this?
I am using Django : Django==2.2 with MySql.
Upvotes: 0
Views: 4303
Reputation: 383
Add username
field in your custom user modal.
Because error clearly says duplicate entry for key username which means, you have overrides the default user authentication by email id, so every time you create a user blank
username tries to be created. Still, Django won't allow it's default implementation to be unique=True
, so you have to override the username attribute also.
class User(AbstractUser):
email = models.EmailField(max_length=100, unique=True)
# add the below one line code
username = models.CharField(max_length=100, unique=False, null=True, default=None)
is_deleted = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
Upvotes: 1
Reputation: 1
I had this problem too, this is for when you sign up and create a new account, for my case, i had one username (""
) in my database and I wanted to create another one with that username again; after deleting the first user, problem solved, but you have to set the user's username first.
Upvotes: 0
Reputation: 122
Set
USERNAME_FIELD = 'username'
and test your code.
If everything works then change it.
Upvotes: 1