Django form does not save password when creating user.

I created a custom form for my django app that allows users to register with the site.

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 click the Submit button, a user is created, however no password has been set for the user

+3


source to share


3 answers


You don't need to touch any fields that are part of User, and in fact you shouldn't, but instead let UserCreationForm handle it because there is special handling for the password there.

Do it like this, in the save method of the form class:

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 cause the TeacherRegistrationForm, which is a subclass of UserCreationForm, which in turn is 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 method conservation. So everything is done for you. Then you just need to handle the extra fields added to the form for another model.

And note that I used the save()

model method instead of using create()

, which does the same thing in this case. But later, you can modify the form code to allow the same form to edit the existing model, rather than just create a new one. Let me know if you would like me to explain this too.

+1


source


Try changing the shape like

def save(self): 
    user = User.objects.create_user(username=self.cleaned_data['username'], password=self.cleaned_data['password1']) 
    user.first_name = self.cleaned_data['first_name']
    user.last_name = self.cleaned_data['last_name']
    user.email = self.cleaned_data['email']
    user.save()
    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

      



Use User.objects.create_user()

instead objects.create

.

I don't see the transfer point request

in the save method. You can remove this part. save

the method is called when executed form.save()

. Also, saving the form again in the form save method isn't really necessary.

+1


source


No need to save the user in your own way, you inherited UserCreationForm

, which will return the user instance after setting a password and validating. So you get a direct instance of the user in the super call.

def save(self, request):       
   user = super(TeacherRegistrationForm, self).save()
   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

      

0


source







All Articles