Trying to create my custom user model, this is the code I have:
models.py
class CustomUser(AbstractUser):
USERNAME_FIELD = 'email'
CustomUser._meta.get_field_by_name('email')[0]._unique=True
settings.py
AUTH_USER_MODEL = 'myapp.CustomUser'
When doing the manage.py syncdb, the following error occurs:
CommandError: One or more models did not validate:
myapp.customuser: The field named as the USERNAME_FIELD should not be included in REQUIRED_FIELDS on a swappable User model.
Can anyone shed some light? Is there a better way of customizing the user model in Django 1.6 without rewriting the entire class extending AbstractBaseUser?
Btw, if I delete USERNAME_FIELD = 'email' from my code and change the core django auth/models.py >> AbstractUser definition, it works. I just can't seem to be able to override the USERNAME_FIELD...
Thanks!
As made clear by the error message, the reason for is that AbstractUser
defines REQUIRED_FIELDS = ['email']
. And you cannot set a field in the REQUIRED_FIELDS
to be your USERNAME_FIELD
. Further detail here.
So if you want email
as your primary field the way forward is to extend and redefine the field email
on AbstractBaseUser
rather than on AbstractUser
.
Also this question/answer pair might be relevant to you in case I did not fully grasp your requirements.
Josvic, your solution partially resolved my issue. What I had to do in the end was this:
class CustomUser(AbstractUser):
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def get_username(self):
return self.email
CustomUser._meta.get_field_by_name('email')[0]._unique=True
This resolved the initial issue that REQUIRED_FIELDS cannot contain the USERNAME_FIELD and as I do not want to redefine the entire User and extend the AbstractBaseUser, I had to include the 'username' in the REQUIRED_FIELD as otherwise the syncdb fails for a different reason (expecting the username for the sake of saving it into the db):
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
TypeError: create_superuser() takes exactly 4 arguments (3 given)
Consequently, when doing the syncdb for the first time and having to enter a superuser, the email must be entered twice, as an email as well as a username. It's awkward but it's the cleanest one that I can live with it.
Cheers!
Josvic hit the nail on the head but I want to provide the solution I used. It's pretty simple.
Remove 'email' or whatever you're using are USERNAME_FIELD
from REQUIRE_FIELDS
.
In the UserManager that you made, simply write:
if not email: raise ValueError('Users must have an email address')
This way, you'll manually enforce that an email is required.
This solution is the one that is used here: https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#a-full-example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With