[Django]-Django 1.5 custom User model error. "Manager isn't available; User has been swapped"

20๐Ÿ‘

โœ…

You need only change form for adding user(overwrite clean_username and change User on get_user_model()

Full working example(If you inherited from AbstractUser)

from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm


class MyUserChangeForm(UserChangeForm):

    class Meta:
        model = get_user_model()

class MyUserCreationForm(UserCreationForm):

    class Meta:
        model = get_user_model()

    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 MyUserAdmin(UserAdmin):
    form = MyUserChangeForm
    add_form = MyUserCreationForm
    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(MyUser, MyUserAdmin)
๐Ÿ‘คnnmware

14๐Ÿ‘

I struggled with this error for hours. For me I needed to remove all references to

from django.contrib.auth.models import User

and then replace it with:

from myapp.models import MyUser as User

This is assuming your custom User model is in an app called myapp and you called the model MyUser.

Iโ€™m using as User so that I donโ€™t have to change where my existing code that makes reference to the the User object from django.contrib.auth.models.

Good luck!

Alan

@aviars

๐Ÿ‘คAlan Viars

4๐Ÿ‘

You probably should look at full example in official documentation:

https://docs.djangoproject.com/en/dev/topics/auth/customizing/#a-full-example

There are some uncovered questions (permissions handling, for example), but, at least, itโ€™s working.

0๐Ÿ‘

From Django docs:

You should also define a custom manager for your User model.

๐Ÿ‘คBula

0๐Ÿ‘

Subclass AbstractUser already handle objects = UserManager() for you (this code on github at line 327). You donโ€™t need to define it in your model again.

Iโ€™m not sure why it come with that error. But below config seem work for me with latest Dev version.

Model.py:

class CustomUser(AbstractUser):
  custom_field = models.ForeignKey('OtherModel')
  # remove : objects = UserManager()
๐Ÿ‘คPattapong J

0๐Ÿ‘

Iโ€™ve found a solution:
I donโ€™t use UserAdmin to register the CustomUser in the admin site, I use a custom ModelAdmin.

class CustomUserAdmin(admin.ModelAdmin):

  add_form = CustomUserCreationAdminForm
  add_fieldsets = (
    (None, {
        'classes': ('wide',),
        'fields': ('username', 'password1', 'password2')}
    ),
  )
  def get_fieldsets(self, request, obj=None):
    if not obj:
        return self.add_fieldsets
    return super(CustomUserAdmin, self).get_fieldsets(request, obj)

  def get_form(self, request, obj=None, **kwargs):
    defaults = {}
    if obj is None:
        defaults.update({
            'form': self.add_form,
            'fields': admin.util.flatten_fieldsets(self.add_fieldsets),
        })
    defaults.update(kwargs)
    return super(CustomUserAdmin, self).get_form(request, obj, **defaults)

Because I want to have a creation form different from the update form, I override the get_form function of the Model Admin as done in the UserAdmin django code. I also have created a custom Creation form for my custom user: CustomUserCreationForm

I received a response in the django-users mailing list that may be better than mine:
Unregister the original User class from the admin site and then register the CustomUser with UserAdmin:

admin.site.unregister(User)
admin.site.register(CustomUser, UserAdmin)

Not tested yet.

EDIT: this last solution doesnโ€™t work

Regards

๐Ÿ‘คnulse

0๐Ÿ‘

UserAdmin is already registered to manage User, at the end of contrib/auth/admin.py

admin.site.register(User, UserAdmin)

Given you want to register UserAdmin with CustomUser, I think you would first have to unregister the User/UserAdmin pair:

admin.site.unregister(User)

then register your new model. Given the lack of control in the order of module loading, you could create a class derived from UserAdmin and manage your user model with it. This would work everytime, if Iโ€™m thinking properly.

๐Ÿ‘คSteve K

Leave a comment