I have a custom user model as below:
class User(AbstractUser):
subscribe_newsletters = models.BooleanField(default=True)
old_id = models.IntegerField
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
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
I had to:
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.
This is due to migration is not run. This issue is resolved for me by running following command:
python manage.py syncdb
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.