I have made a custom form for my django app which allows users to register themselves for the website.
This is the form for my django app:
class TeacherRegistrationForm(UserCreationForm):
email = forms.EmailField(required = True)
school = forms.CharField(required = True)
subject = forms.CharField(required = True)
head_of_subject = forms.BooleanField(required = False)
identification_code = forms.CharField(required = True)
def __init__(self, *args, **kwargs):
super(TeacherRegistrationForm, self).__init__(*args, **kwargs)
self.fields['username'].help_text = ''
self.fields['password2'].help_text = ''
class Meta:
model = User
fields = (
'username',
'first_name',
'last_name',
'email',
'school',
'identification_code',
'subject',
'head_of_subject',
'password1',
'password2'
)
def save(self, request):
form = TeacherRegistrationForm(request.POST)
user = User.objects.create(first_name=self.cleaned_data['first_name'],
last_name=self.cleaned_data['last_name'],
email=self.cleaned_data['email'],
username=self.cleaned_data['username'],
password=self.cleaned_data['password1']
)
teacher_profile = TeacherProfile.objects.create(user=user,
school=self.cleaned_data['school'],
subject=self.cleaned_data['subject'],
head_of_subject=self.cleaned_data['head_of_subject'],
)
return user, teacher_profile
This is the relevant part of the view:
if request.method == 'POST':
form = TeacherRegistrationForm(request.POST)
entered_school_name = form['school'].value()
entered_school_id = form['identification_code'].value()
actual_school_id = SchoolProfile.objects.get(school_name__exact = entered_school_name).identification_code
if form.is_valid()and (entered_school_id == actual_school_id):
user, teacher_profile = form.save(request)
return render(request, 'accounts/home.html')
else:
args = {'form': form}
return render(request, 'accounts/reg_form.html', args)
When I press submit, the user is created, however no password is set for the user
There's no need to touch any of the fields that are part of User, and in fact you shouldn't do that but instead let the UserCreationForm handle it because there's some special handling for password in there.
Do it like so, in your form class save method:
def save(self):
user = super(TeacherRegistrationForm, self).save()
teacher_profile = TeacherProfile(
user=user,
school=self.cleaned_data['school'],
subject=self.cleaned_data['subject'],
head_of_subject=self.cleaned_data['head_of_subject']
)
teacher_profile.save()
return user, teacher_profile
This will result in the TeacherRegistrationForm, which is a subclass of UserCreationForm, which is in turn a subclass of ModelForm.. will do what ModelForm is supposed to do, which is to save itself to the database (user table) when you call its save method. So that's all done for you. Then you just have to handle the extra fields you added to the form for the other model.
And notice I used the model save()
method instead of using create()
, which in this case accomplishes the same thing.. but you could later on modify the form code to allow the same form to edit an existing model not just create a new one. Let me know if you would like me to explain that too.
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