15

I have a custom user model as below:

class User(AbstractUser):
    subscribe_newsletters = models.BooleanField(default=True)
    old_id = models.IntegerField(null=True, blank=True)
    old_source = models.CharField(max_length=25, null=True, blank=True)

And using the builtin UserAdmin

admin.site.register(User, UserAdmin)

While editing the user record works fine, but when I add a user, I get the following error

Exception Value: 
relation "auth_user" does not exist
LINE 1: ...user"."is_active", "auth_user"."date_joined" FROM "auth_user...

6 Answers 6

28

After some digging around I found this

https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#custom-users-and-the-built-in-auth-forms

The culprit is a function clean_username inside UserCreationForm inside django.contrib.auth.forms.py. A few tickets have been created, but apparently the maintainers don't think it's a defect:

https://code.djangoproject.com/ticket/20188

https://code.djangoproject.com/ticket/20086

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:
            User._default_manager.get(username=username)
        except User.DoesNotExist:
            return username
        raise forms.ValidationError(self.error_messages['duplicate_username'])

The User in this file is directly referencing to the builtin user model.

To fix it, I created my custom forms

from models import User #you can use get_user_model
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth import forms

class MyUserCreationForm(UserCreationForm):
    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:
            User._default_manager.get(username=username)
        except User.DoesNotExist:
            return username
        raise forms.ValidationError(self.error_messages['duplicate_username'])

    class Meta(UserCreationForm.Meta):
        model = User

class MyUserAdmin(UserAdmin):  
    add_form = MyUserCreationForm   

admin.site.register(User,MyUserAdmin)

Or you can try monkey patching the original UserCreationForm to replace the User variable.

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

4 Comments

Nice catch. This should definitely be addressed considering the Django docs actually encourage you to to use these classes right out of the box when you extend the User model.
Just the solution I'm looking for.
Thanks! Just one small thing, your code example is missing an import: from django.contrib.auth import forms
The first link you bring is broken
12

Django 1.8

If your app is not yet using migrations then this could also be the problem, as contrib.auth uses them. Enabling migrations for my app solved it for me.

$ ./manage.py makemigrations <my_app>
$ ./manage.py migrate

2 Comments

You saved my sanity. Apparently if you wipe migrations, you need to keep the migration folder and __init__.py in it, otherwise Django will fail to create the initial migration, and subsequently fail migrate.
Had to specify the name of the app. Without it I was getting No changes detected.
5

This is due to migration is not run. This issue is resolved for me by running following command:

python manage.py syncdb

1 Comment

3

Migrate your app (the one with custom user model) first, and only then the rest:

$ ./manage.py makemigrations <your_app>
$ ./manage.py migrate
$ ./manage.py makemigrations
$ ./manage.py migrate

You can also control the order of migrations to make sure this happens automatically, see https://docs.djangoproject.com/en/1.10/howto/writing-migrations/#controlling-the-order-of-migrations

Comments

0

I had to:

  1. delete the database
  2. create a new database
  3. delete all migrations from all models
  4. make migrations anew
  5. migrate

It was double annoying because I had to do it on local and remote server. I tried just deleting migrations or deleting the database but then git would push/pull the old migrations and messed everything up.

P.S. This bug initially arose because I ran the migrations before adding AUTH_USER_MODEL = 'customauth.MyUser' to the settings.py file, which is not version controlled.

Comments

0

You haven't created the admin in the database. If you are using an up to date version of Django

Try:

python manage.py makemigrations
python manage.py migrate

Am a bit curious about how you can have a login and password if the auth tables don't exist?

The last command saved me a lot of time

Comments

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.