简体   繁体   English

Django在创建用户时不保存密码

[英]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. 我为我的django应用程序制作了一个自定义表单,允许用户为网站注册。

This is the form for my django app: 这是我的django应用程序的表单:

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. 没有必要触及属于User的任何字段,事实上你不应该这样做,而是让UserCreationForm处理它,因为那里有一些特殊的密码处理。

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. 这将导致TeacherRegistrationForm,它是UserCreationForm的子类,而UserCreationForm又是ModelForm的子类..将执行ModelForm应该做的事情,即当你调用它时保存到数据库(用户表)方法。 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. 并注意我使用了模型save()方法而不是使用create() ,在这种情况下完成相同的事情..但您可以稍后修改表单代码以允许相同的表单编辑现有模型而不仅仅创建一个新的一个。 Let me know if you would like me to explain that too. 如果您希望我也解释一下,请告诉我。

Try editing your form like this, 尝试像这样编辑表单,

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() rather than objects.create . 使用User.objects.create_user()而不是objects.create

I don't see the point of passing request into the save method. 我没有看到将request传递给save方法的重点。 You can remove that part. 您可以删除该部分。 save method is called when form.save() is executed. 执行form.save()时调用save方法。 Also, saving form again in the form save method is actually unnecessary. 另外,在表单保存方法中再次保存表单实际上是不必要的。

No need of save user in custom way, you inherited UserCreationForm that will return user instance after set password and with validation So you will get direct user instance in super call. 无需以自定义方式保存用户,您继承了UserCreationForm ,它将在设置密码后通过验证返回用户实例,因此您将在超级调用中获得直接用户实例。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM