I created a Profile model with Django. The profile inherits from a CustomUser class which I wrote by inheriting AbstractBaseUser. However, when I go to the sign up page, even though first_name and last_name are required in the Custom User class, it doesn't show. It only shows the fields of the profile model, and email and password. I am using Django all auth.
How do I make the required fields of the custom user (and other fields I want e.g middle_name) and the fields of the profile all show up in the same form, and still save both the custom user model, and the profile model in the database all at the same time?
models.py
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
USER_TYPE_CHOICES = (
(1, 'student'),
(2, 'department'),
(3, 'admin'),
)
first_name = models.CharField(max_length=70, blank=False, default="")
middle_name = models.CharField(max_length=70, blank=False, default="")
last_name = models.CharField(max_length=70, blank=False, default="")
is_active = models.BooleanField(default=True)
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES)
is_staff = models.BooleanField(default=False) # a admin user; non super-user
is_superuser = models.BooleanField(default=False) # a superuser
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name'] # Email & Password are required by default.
objects = UserManager()
# I left out some unimportant code
class StudentUser(models.Model):
# This is the model class for students
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
matric_number = models.CharField(max_length=11, blank=False)
department = models.CharField(max_length=40, blank=False)
views.py:
from users.forms import StudentUserSignupForm
from allauth.account.views import SignupView
class StudentUserSignupView(SignupView):
# The referenced HTML content can be copied from the signup.html
# in the django-allauth template folder
template_name = 'account/signup.html'
# the previously created form class
form_class = StudentUserSignupForm
forms.py:
class UserCreationForm(forms.ModelForm):
"""
A form for creating new users. Includes all the required
fields, plus a repeated password.
"""
class Meta:
model = User
fields = ('email', 'first_name', 'last_name')
def save(self, commit=True):
user = super(UserChangeForm, self).save(commit=False)
# Save the provided password in hashed format
if self.cleaned_data.get("password1"):
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
# I removed some unimportant code
class StudentUserSignupForm(SignupForm):
first_name = forms.CharField(max_length=70)
middle_name = forms.CharField(max_length=70, required=False)
last_name = forms.CharField(max_length=70)
matric_no = forms.CharField(min_length=10, max_length=11)
department = forms.CharField(max_length=40)
def save(self, request):
# Save the User instance and get a reference to it
user_form = super(StudentUserSignupForm, self).save(request)
# user_form.user_type = 1 To correct
student_user = StudentUser(
user=user_form,
matric_no=self.cleaned_data.get('matric_number'),
department=self.cleaned_data.get('department')
)
student_user.save()
return student_user.user
html template
<div class="row justify-content-center align-items-center">
<div class="col-auto m-auto">
<div class="jumbotron mt-4">
<h3>Sign Up</h3>
<form method="post">
{% csrf_token %}
{% for field in form %}
{{ field|add_class:"form-control-sm"|as_crispy_field }}
{% endfor %}
<button class="btn btn-sm btn-primary" type="submit">Sign Up</button>
</form>
</div>
</div>
You see that in the image above, it shows email, password, and department, but it does not show first_name, last_name, middle_name etc. How do I make the required and non required fields of the User model show up in the form and still save both models? Does the issue have anything to do with django-allauth?