AUTH_USER_MODEL refers to model .. that has not been installed and created AbstractUser models not able to login

Question:

AUTH_USER_MODEL error solved in EDIT3. Passwords still will not save on user creation via form.

I’m using Django 1.5 playing around with the new user override/extension features, and I am not able to register new users via my registration form – only via the Admin. When registering via the registration form, I get the following error:

Manager isn't available; User has been swapped for 'poker.PokerUser'

models.py:

class PokerUser(AbstractUser):
    poker_relate = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
    token = models.EmailField()
    USER_CHOICES = (
        ('1', 'Staker'),
        ('2', 'Horse')
    )
    user_type = models.CharField(choices=USER_CHOICES, max_length=10)
    username1 = models.CharField(null=True, blank=True, max_length=40)
    username2 = models.CharField(null=True, blank=True, max_length=40)
    username3 = models.CharField(null=True, blank=True, max_length=40)
    username4 = models.CharField(null=True, blank=True, max_length=40)
    username5 = models.CharField(null=True, blank=True, max_length=40)

PokerUserForm model:

class PokerUserForm(UserCreationForm):
    class Meta:
        model = PokerUser
        fields = ('username','password1','password2','email','user_type','token','username1','username2','username3','username4','username5',)

I’ve attempted to change the model in the PokerUserForm model to use get_user_model() instead of explicitly defining the model by setting model = get_user_model() instead of model = PokerUser but then I receive the following error:

django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed

My AUTH_USER_MODEL is setup in my settings.py like so:

AUTH_USER_MODEL = 'poker.PokerUser'

On we go – my Registration view in views.py:

def UserRegistration(request):
    player = PokerUser()

    if request.method == 'POST':
        form = PokerUserForm(request.POST, instance=player)
        if form.is_valid():
            player.email_address = form.cleaned_data['email']
            player.user_type = form.cleaned_data['user_type']
            # if player is staker, token is their own email. otherwise their token is their staker's email and
            # their relation is their staker
            if player.user_type == '1' or player.user_type == 'staker':
                player.token = player.email_address
            else:
                player.token = form.cleaned_data['token']
                staker = PokerUser.objects.get(email=player.token)
                player.poker_relate = staker
            player.save()
            return HttpResponseRedirect('/')
    else:
        form = PokerUserForm()
    initialData = {'form': form}
    csrfContext = RequestContext(request, initialData)
    return render_to_response('registration/register.html', csrfContext)

EDIT1:

According to the docs, the UserCreationForm must be recreated for use with custom user classes.

I overrode the entire UserCreationForm as follows:

class UserCreationForm(forms.ModelForm):
    """
    A form that creates a user, with no privileges, from the given username and
    password.
    """
    error_messages = {
        'duplicate_username': _("A user with that username already exists."),
        'password_mismatch': _("The two password fields didn't match."),
        }
    username = forms.RegexField(label=_("Username"), max_length=30,
        regex=r'^[w.@+-]+$',
        help_text=_("Required. 30 characters or fewer. Letters, digits and "
                    "@/./+/-/_ only."),
        error_messages={
            'invalid': _("This value may contain only letters, numbers and "
                         "@/./+/-/_ characters.")})
    password1 = forms.CharField(label=_("Password"),
        widget=forms.PasswordInput)
    password2 = forms.CharField(label=_("Password confirmation"),
        widget=forms.PasswordInput,
        help_text=_("Enter the same password as above, for verification."))

    class Meta:
        model = PokerUser
        fields = ('username','password1','password2','email','user_type','token','username1','username2','username3','username4','username5',)

    def clean_username(self):
        # Since User.username is unique, this check is redundant,
        # but it sets a nicer error message than the ORM. See #13147.
        username = self.cleaned_data["username"]
        try:
            PokerUser.objects.get(username=username)
        except PokerUser.DoesNotExist:
            return username
        raise forms.ValidationError(self.error_messages['duplicate_username'])

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'])
        return password2

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

And this was able to resolve this error:

The Manager isn't available; User has been swapped for 'poker.PokerUser'

Now, the users get created but are not able to log in. When I check the users in the admin, all of the information seems to be correct except for the password. Adding a password manually in the admin does not seem to work correctly. Still, adding users via the admin work correctly.

EDIT 2:

I’m still unable to login as any of my AbstractUser models created via the registration form. I have completely overridden the UserCreationForm as outlined above, and am unable to implement
get_user_model() with this error:

AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed

The Django code for get_user_model() is:

 def get_user_model():
    "Return the User model that is active in this project"
    from django.conf import settings
    from django.db.models import get_model

    try:
        app_label, model_name = settings.AUTH_USER_MODEL.split('.')
    except ValueError:
        raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
    user_model = get_model(app_label, model_name)
    if user_model is None:
        raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL)
    return user_model

Since I have AUTH_USER_MODEL = 'poker.PokerUser' setup in my settings.py, this should work. I’ve verified this through the Django console:

>>> from django.contrib.auth import get_user_model
>>> settings.AUTH_USER_MODEL
Out[14]: 'poker.PokerUser'
>>> from django.db.models import get_model
>>> app_label, model_name = settings.AUTH_USER_MODEL.split('.')
>>> user_model = get_model(app_label, model_name)
>>> user_model
Out[18]: poker.models.PokerUser

However the implementation still does not work correctly.

If you’ve read this far, thanks!

EDIT3:

AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed has been fixed. I accidentally had the UserCreationForm that I recreated in poker.models instead of registration.forms, so when I ran get_user_model() that was assigned to poker.PokerUser, it couldn’t resolve since it was already in that location.

Now the only issue left is that when creating new users, their passwords will not save. I’ve narrowed it down to a single method in the UserCreationForm by placing print statements here:

def clean_password2(self):
    password1 = self.cleaned_data.get("password1")
    print password1
    password2 = self.cleaned_data.get("password2")
    print password2
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError(
            self.error_messages['password_mismatch'])
    print password2
    return password2

def save(self, commit=True):
    user = super(UserCreationForm, self).save(commit=False)
    user.set_password(self.cleaned_data["password1"])
    print self.cleaned_data["password1"]
    if commit:
        user.save()
    return user

The print password1 and print password1 statements in clean_password2 display the plain text password, but print self.cleaned_data["password1"] in the save method is blank. Why is my form data not being passed to the save method?

TL;DR AbstractUser model creation is working in both Admin and via registration form, but only the users created via Admin are able to login. The users created via the registration form are unable to log in and seem to be saved without a password – all other information is saved correctly.

Asked By: Dan Hoerst

||

Answers:

Ok there were three issues here for me, so I’m going to address all of them since I am pretty sure the first two will come up for someone else.

  • Manager isn't available; User has been swapped for 'poker.PokerUser'

This was due to using but not recreating the UserCreationForm. When using custom models in 1.5, some model forms are available out of the box but this one must be recreated. See here for the docs.

  • The Manager isn't available; User has been swapped for 'poker.PokerUser'

While I had AUTH_USER_MODEL = 'poker.PokerUser' set in my settings.py, I was calling get_user_model() from the poker.models location. You must call get_user_model() from a different location. Moving my form to registration.forms and calling get_user_model() from there worked correctly.

  • New users not saving

This was just a brain fart on my end. In my UserRegistration model I was manipulating various fields from the form. When I passed those fields back to UserCreationForm for the save() method, I was not passing the password fields with it. Woops!

Answered By: Dan Hoerst

I’ve run into this a few times. It’s always been an import issue. Suppose we have core/models.py that implements a custom user and imports a symbol from another file (say Else):

from Something import Else

class CustomUser(AbstractBaseUser):
    pass

And then we have another file that uses CustomUser and also defines Else. Let’s call this something/models.py:

from core.models import CustomUser

class Else(models.Model):
    pass

class AnotherClass(models.model):
    user = models.ForeignKey(CustomUser)

When core/models.py goes to import Else, it evaluates something/models.py and runs into the AnotherClass definition. AnotherClass uses CustomUser, but CustomUser hasn’t been installed yet because we’re in the process of creating it. So, it throws this error.

I’ve solved this problem by keeping my core/models.py standalone. It doesn’t import much from my other apps.

Answered By: Rob Jones

In my case updating, proper app_label in meta solved this issue

class APPUser(AbstractUser):
   password = models.TextField(blank=True)

   class Meta:
     app_label = 'app_auth'
     db_table = "app_user"
Answered By: naren

It can happen if you forget to register your app in settings. In your settings.py file add the name of your app in the list of INSTALLED_APPS. I hope this helps.

For instance, if your app name is ‘users’ it would look like this:

INSTALLED_APPS = [
  ......

  'users'
]
Answered By: birajad

In my case, I override the built-in User model and made the class abstract that caused this issue. Therefore, changing abstract=False in metaclass resolved the issue.

class User(AbstractBaseUser, PermissionMixin):
      email = models.EmailField(max_length=255)

      class Meta:
      abstract = False
Answered By: hasan najeeb

If you created multiple directory to maintain structure in your project, Check directory of the User model that you have written.
Just import the User model in init.py of that directory.

Example:

app directory: 
     app/
       views/
         __init__.py
         views.py
       models/
         __init__.py  ->  from .user_model import User
         user_model.py -> class User(AbstractUser):

In my case i got the solution in this way.

Answered By: sani khan
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.