I have extended the UserCreationForm of Django to add extra fields : Email and Choice field. Now when I am filling those details in the registration form and submitting it. Only the email is stored in the database and not the choice field(i.e status in the code). However when I am viewing the fields of my form in the console the choice field is showing. But when I am accessing the attribute using the django shell I am getting an error
from django.contrib.auth.models import User
users = User.objects.all()
users[6].email
Output : masterhimanshupoddar@gmail.com # success
users[6].status
Error: AttributeError Traceback (most recent call last)
<ipython-input-7-c9d2701fa919> in <module>()
----> 1 users[6].status
AttributeError: 'User' object has no attribute 'status'
Here is my forms.py
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
STATUS_CHOICES = (
(1, ("CEO")),
(2, ("Dev Manager")),
(3, ("Testing Manager")),
(4, ("Developer")),
(5, ("Test Engineer"))
)
email = forms.EmailField(required=True,
label='Email',
error_messages={'exists': 'Oops'})
status = forms.ChoiceField(choices = STATUS_CHOICES, label="Designation", initial='Developer', widget=forms.Select(), required=True)
class Meta:
model = User
fields = ("username", "email", "password1", "password2", "status")
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
user.status = self.cleaned_data["status"]
if commit:
user.save()
return user
Why am I getting error?
It is not enough to add the field to your form, you also have to add it to the model.
For that, you need to create a custom user class in your models.py
:
from django.contrib.auth.models import AbstractUser
STATUS_CHOICES = (
(1, ("CEO")),
(2, ("Dev Manager")),
(3, ("Testing Manager")),
(4, ("Developer")),
(5, ("Test Engineer"))
)
class User(AbstractUser):
status forms.ChoiceField(choices = STATUS_CHOICES, verbose_name ="Designation")
Then you have to change the settings AUTH_USER_MODEL
to point to your model accordingly. Assuming the app which contains your new custom user model is called my_app
, the setting would look like this:
AUTH_USER_MODEL = 'my_app.User'
You also have to make sure that any ForeignKey
fields in your model use AUTH_USER_MODEL
instead of django.contrib.auth.models.User
:
from django.conf import settings from django.db import models
class Article(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
Also don't forget to create and apply database migrations:
python manage.py makemigrations
python manage.py migrate
Unfortunately, changing the user model mid-project can lead to tricky problems, so if you are still early in your project, it might be easiest to delete and recreate your database.
Refer to your model with get_user_model()
in your form:
from django.contrib.auth import get_user_model
class SignUpForm(UserCreationForm):
...
class Meta:
model = get_user_model()
Please refer to the documentation on Substituting a custom User model