Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django form not saving password when creating user

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

like image 887
wtreston Avatar asked Oct 18 '22 11:10

wtreston


1 Answers

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.

like image 198
little_birdie Avatar answered Oct 27 '22 08:10

little_birdie