Reputation: 2016
Folks,
I'm trying to create my own User model by extending the AbstractBaseUser model provided by Django.
However, I keep on getting the following error when migrating:
ValueError: The field admin.LogEntry.user was declared with a lazy reference to '<app_name>.user', but app '<app_name>' doesn't provide model 'user'.
What I have done so far is the following:
In app/models.py
added CustomUser class together with CustomUserManager with relevant fields and all.
In app/admin.py
I've added this:
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from <app_name>.models import CustomUser
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
fields = ('email',)
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = ('email',)
def clean_username(self):
username = self.cleaned_data["username"]
try:
get_user_model().objects.get(username=username)
except get_user_model().DoesNotExist:
return username
raise forms.ValidationError(self.error_messages['duplicate_username'])
class CustomUserAdmin(UserAdmin):
form = CustomUserChangeForm
add_form = CustomUserCreationForm
fieldsets = (
(None, {'fields': [('username', 'password'),]}),
(('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
(('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
admin.site.register(CustomUser, CustomUserAdmin)
Apart from that there is this added to seetings.py
AUTH_USER_MODEL = '<app_name>.CustomUser'
Everything that I found so far suggests that the above given code should make this work, but it doesn't. I spent like 4-5 hours already and I still can't get my head around it. Someone please help
Upvotes: 1
Views: 458
Reputation: 555
Create your User model like so:
from django.core import validators
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.models import UserManager
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(_('username'), max_length=75, unique=True,
help_text=_('Required. 30 characters or fewer. Letters, numbers and '
'underscores characters'),
validators=[
validators.RegexValidator(re.compile('^[\w]+$'),
_('Enter a valid username.'), 'invalid')
])
first_name = models.CharField(_('first name'), max_length=254, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('email address'), max_length = 254, unique = True, null = True)
is_staff = models.BooleanField(_('staff status'), default=False,
help_text=_('Designates whether the user can log into this admin '
'site.'))
is_active = models.BooleanField(_('active'), default=True,
help_text=_('Designates whether this user should be treated as '
'active. Unselect this instead of deleting accounts.'))
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['first_name']
def get_full_name(self):
return self.name
def get_short_name(self):
return self.username
Don't forget to add your custom fields!
Use a custom admin like so:
@admin.register(models.User)
class CustomUserAdmin(UserAdmin):
list_display = ('name', 'username', 'is_staff', )
list_filter = ('is_staff', )
search_fields = ('first_name', 'last_name', 'username', )
readonly_fields = ('date_joined', 'last_login', )
fieldsets = (
(None, {
'fields': ('username', 'password')
}),
("Personal Information", {
'fields': ('first_name', 'last_name', 'email')
}),
("Permissions", {
'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')
}),
("Important Dates", {
'fields': ('last_login', 'date_joined')
}),
)
Then finally add it to your settings:
AUTH_USER_MODEL = '<app_name>.User'
A working demonstration can be found in my GitHub repository.
Upvotes: 1