to_field Django custom user model in admin, relation “auth_user” does not exist
programmingerror at/admin/login/ (4)
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
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...
After some digging around I found this
The culprit is a function
django.contrib.auth.forms.py. A few tickets have been created, but apparently the maintainers don't think it's a defect:
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'])
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
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
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
I had to:
- delete the database
- create a new database
- delete all migrations from all models
- make migrations anew
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.