Manager isn't available; 'auth.User' has been swapped for 'common.User'

2,852 views
Skip to first unread message

Mike Dewhirst

unread,
Nov 16, 2017, 4:19:24 AM11/16/17
to Django users
Any hints appreciated. I'm stumped. Traceback at the end.

Many thanks

Mike

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

I have a custom user based on AbstractUser plus a UserProfile model as follows:

#common.models
from django.conf import settings
from django.contrib.auth.models import AbstractUser, Group, UserManager
from django.db import models
from django.utils.encoding import python_2_unicode_compatible


@python_2_unicode_compatible
class User(AbstractUser):

    objects = UserManager()

    class Meta:
        abstract = False

    def __str__(self):
        grps = u''
        superuser = u''
        if self.is_staff:
            superuser = u' [Staff]'
        if self.is_superuser:
            superuser = u' [Superuser]'
        if not self.is_active:
            superuser += u' [Inactive]'
        groups = Group.objects.filter(user=self).order_by('name')
        if groups:
            grps = u', '.join(grp.name for grp in groups)
        if grps:
            grps = u' (%s)' % grps
        grps += superuser
        return u'%s%s' % (self.username, grps)

    def save(self, *args, **kwargs):
        super(User, self).save(*args, **kwargs)
        # not sure whether to use the post-save signal or just save it here
        profile = UserProfile.objects.get_or_create(user=self)[0]
        profile.save()


@python_2_unicode_compatible
class UserProfile(models.Model):

    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        related_name='userprofile',
        on_delete=models.CASCADE,
    )
    ...
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'user profile'
        verbose_name_plural = 'user profile'

    def __str__(self):
        return u'%s' % self.user

The error occurs when I click [Register] with a new user via the following view:

#common.views
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect

def register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=username, password=raw_password)
            login(request, user)
            return redirect('common.views.homepage')
    else:
        form = UserCreationForm()
    return render(request, 'register.html', {'form': form})

For completeness here is the template:

#register.html 
{% extends 'base_site.html' %}
{% block content %}
  <h2>Register</h2>
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Register</button>
  </form>
{% endblock %}

 
Traceback ...

Environment:


Request Method: POST
Request URL: http://localhost:8000/register/

Django Version: 1.11.6
Python Version: 3.6.1
Installed Applications:
['django.contrib.admin',
 'django.contrib.admindocs',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sites',
 'common',
 'course',
 'credit']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "C:\Users\mike\env\xxct3\lib\site-packages\django\core\handlers\exception.py" in inner
  41.             response = get_response(request)

File "C:\Users\mike\env\xxct3\lib\site-packages\django\core\handlers\base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\mike\env\xxct3\lib\site-packages\django\core\handlers\base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\mike\env\xxct3\train\common\views.py" in register
  36.         if form.is_valid():

File "C:\Users\mike\env\xxct3\lib\site-packages\django\forms\forms.py" in is_valid
  183.         return self.is_bound and not self.errors

File "C:\Users\mike\env\xxct3\lib\site-packages\django\forms\forms.py" in errors
  175.             self.full_clean()

File "C:\Users\mike\env\xxct3\lib\site-packages\django\forms\forms.py" in full_clean
  386.         self._post_clean()

File "C:\Users\mike\env\xxct3\lib\site-packages\django\forms\models.py" in _post_clean
  413.             self.instance.full_clean(exclude=exclude, validate_unique=False)

File "C:\Users\mike\env\xxct3\lib\site-packages\django\db\models\base.py" in full_clean
  1235.             self.clean()

File "C:\Users\mike\env\xxct3\lib\site-packages\django\contrib\auth\models.py" in clean
  349.         self.email = self.__class__.objects.normalize_email(self.email)

File "C:\Users\mike\env\xxct3\lib\site-packages\django\db\models\manager.py" in __get__
  198.                     cls._meta.swapped,

Exception Type: AttributeError at /register/
Exception Value: Manager isn't available; 'auth.User' has been swapped for 'common.User'






Mike Dewhirst

unread,
Nov 16, 2017, 6:32:29 AM11/16/17
to Django users
The fix is to adjust 1.11 django.contrib.auth.forms as follows:

Line 12 - comment it right out
Line 88 - change User to UserModel
Line 128 - change User to UserModel

Here is the diff ...

@@ -9,7 +9,7 @@ from django.contrib.auth import (
 from django.contrib.auth.hashers import (
     UNUSABLE_PASSWORD_PREFIX, identify_hasher,
 )
-from django.contrib.auth.models import User
+#from django.contrib.auth.models import User
 from django.contrib.auth.tokens import default_token_generator
 from django.contrib.sites.shortcuts import get_current_site
 from django.core.mail import EmailMultiAlternatives
@@ -85,7 +85,7 @@ class UserCreationForm(forms.ModelForm):
     )

     class Meta:
-        model = User
+        model = UserModel
         fields = ("username",)
         field_classes = {'username': UsernameField}

@@ -125,7 +125,7 @@ class UserChangeForm(forms.ModelForm):
     )

     class Meta:
-        model = User
+        model = UserModel
         fields = '__all__'
         field_classes = {'username': UsernameField}

Cheers

Mike
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-users...@googlegroups.com
> <mailto:django-users...@googlegroups.com>.
> To post to this group, send email to django...@googlegroups.com
> <mailto:django...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/0d3930be-30cb-8dc8-d0c9-a8f34e46e781%40dewhirst.com.au
> <https://groups.google.com/d/msgid/django-users/0d3930be-30cb-8dc8-d0c9-a8f34e46e781%40dewhirst.com.au?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

Mike Dewhirst

unread,
Nov 16, 2017, 6:38:00 AM11/16/17
to Django users
Seems to have pushed the error a bit further down the line. Still in
trouble.

Mike
--

Climate Pty Ltd
PO Box 308
Mount Eliza
Vic 3930
Australia +61

T: 03 9034 3977
M: 0411 704 143


Mike Dewhirst

unread,
Nov 16, 2017, 6:51:49 AM11/16/17
to Django users
Fixed it again. It works for me but no guarantees.

Reverted previous changes and ...
Insert line 23 - User = get_user_model()

This needs someone above my pay grade.

Cheers

Mike

James Schneider

unread,
Nov 16, 2017, 6:54:56 AM11/16/17
to django...@googlegroups.com


On Nov 15, 2017 8:18 PM, "Mike Dewhirst" <mi...@dewhirst.com.au> wrote:
Any hints appreciated. I'm stumped. Traceback at the end.

Many thanks

Mike

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

I have a custom user based on AbstractUser plus a UserProfile model as follows:

#common.models
from django.conf import settings
from django.contrib.auth.models import AbstractUser, Group, UserManager
from django.db import models
from django.utils.encoding import python_2_unicode_compatible


@python_2_unicode_compatible
class User(AbstractUser):

    objects = UserManager()

    class Meta:
        abstract = False

Dumb question. I'm assuming you've set AUTH_USER_MODEL to use your new user model?

Also, the Django contrib user model has a meta option for swappable, perhaps you need to set that since you are overriding the Meta class?

class Meta:
    abstract = False
    swappable = True


Your Meta could also inherit from AbstractUser.Meta. Or better yet, since abstract = False by default, just remove the entire Meta class and let the defaults reign.

I have seen several tickets where the devs are playing with this option, calling it a 'stealth new feature' and leaving it undocumented intentionally, but it has something to do with changing out the user model on existing projects.

-James
Reply all
Reply to author
Forward
0 new messages