I initially created a project using abstractuser but have since discovered that it still has a requirement for a username, even when specifying USERNAME_FIELD = email.
If i set username = None in the model it will generate an error during migrations, if I take this out the migrations will pass but then my custom user create form fails .is_valid() with the form.error saying username is required.
I have tried changing from abstractuser to abstractbaseuser class but during migrations it fails saying username field is unknown in customuser.
My question is whether its possible to change from abstractuser to abstractbaseuser mid project or do I need to reset all migrations, truncate migrations table in DB and start migrations again?
Code below just in case:
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
class UserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('The Email field must be set')
user = self.model(email=self.normalize_email(email), **extra_fields,)
user.set_password(password)
user.save(using=self._db)
print("user save from UserManager.create_user method")
return user
def create_superuser(self, email, password=None, **extra_fields):
user = self.create_user(email, password=password, **extra_fields,)
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class CustomUser(AbstractBaseUser, PermissionsMixin):
username = None
email = models.EmailField(unique=True, db_index=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
phone = models.IntegerField(null=False, blank=False)
is_verified = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['phone']
def __str__(self):
return self.email
def get_full_name(self):
return f"{self.first_name} {self.last_name}"
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from members.models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = UserCreationForm.Meta.fields + ('phone',)
class CustomerUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = UserChangeForm.Meta.fields
admin.py
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.exceptions import ValidationError
from .models import CustomUser
class UserCreationForm(forms.ModelForm):
""" form to create new users, includes required fields and repeated password """
password1 = forms.CharField(label="Password", widget=forms.PasswordInput)
password2 = forms.CharField(label="Password confirmation", widget=forms.PasswordInput)
class Meta:
model = CustomUser
fields = ("email", "phone",)
def clean_password2(self):
""" check both passwords match"""
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserChangeForm(forms.ModelForm):
""" form to update users, includes all fields and password hash """
password = ReadOnlyPasswordHashField()
class Meta:
model = CustomUser
fields = ("email", "password", "phone", "is_active", "is_staff")
class CustomUserAdmin(UserAdmin):
add_form = UserCreationForm
form = UserChangeForm
model = CustomUser
list_display = ["email", "phone"]
search_fields = ["email", "first_name", "last_name"]
fieldsets = [
("Access info", {"fields": ["email", "passsword"]}),
("Personal info", {"fields": ["phone"]}),
]
add_fieldsets = [
(
None,
{
"classes": ["wide"],
"feilds": ["email", "first_name", "last_name", "phone", "password1", password2"],},
),
]
search_fields = ["email"]
ordering = ["email"]
admin.site.register(CustomUser, CustomUserAdmin)
admin.site.unregister(Group)