Hi Everyone,
I use Django since a while and Im working on a simple project where user login with email but also have a required username on user creation.
Here’s my user models.py
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
from django.utils import timezone
from django.contrib.auth.models import PermissionsMixin
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, email, username, password, **extra_fields):
# if not username:
# raise ValueError('Nom utilisateur requis')
# if not email:
# raise ValueError('Addresse courriel requis')
email = self.normalize_email(email)
username = username.strip()
user = self.model(email=email, username=username, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, username, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, username, password, **extra_fields)
def create_superuser(self, email, username, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
return self._create_user(email, username, password, **extra_fields)
# the custom user model
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(
'Nom utilisateur', max_length=50, unique=True)
is_staff = models.BooleanField('staff status', default=False)
is_active = models.BooleanField('active', default=True)
is_superuser = models.BooleanField('superuser', default=False)
date_joined = models.DateTimeField('date joined', default=timezone.now)
email = models.EmailField("Courriel", max_length=255, unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
def __str__(self):
return self.username
def get_username(self):
return self.username
Here’s my admin.py
from typing import Any
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
from django.utils.translation import gettext_lazy as _
class CustomUserAdmin(UserAdmin):
model = User
"""Define admin model for custom User model with no username field."""
fieldsets = (
(None, {'fields': ('username', 'email', 'password')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'email', 'password',),
}),
)
list_display = ('username', 'email', 'is_staff')
search_fields = ('username', 'email')
ordering = ('email', 'username')
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
admin.site.register(User, CustomUserAdmin)
Now when I create a super user from shell : email, username, password has to be filled correctly.
Then I log in with these credential on admin panel and it work.
All appear right but for instance, when I add a group to my user and I save, the email value become the email value. I checked in database and effectively the email entry is now same to the username entry.
I tried various way, trying to backtrack the problem and my though is the problem come from the
django/contrib/admin/options.py
but maybe not. I need help.
please focus on positive comment. I’d like to improve my understanding. Thank you