1

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

1

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

just to add to that, this should be the very first change that you make to your app, e.g. migration 0001_initial.py, otherwise it doesn't work due to the error posted in the question. thanks a lot for your help though!!
No problem, I'm happy to help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.