【问题标题】:Django form not saving password when creating user创建用户时Django表单不保存密码
【发布时间】:2017-06-13 17:03:19
【问题描述】:

我为我的 django 应用制作了一个自定义表单,允许用户为网站注册自己。

这是我的 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

这是视图的相关部分:

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)

当我按下提交时,用户被创建,但是没有为用户设置密码

【问题讨论】:

    标签: python django django-forms


    【解决方案1】:

    没有必要触摸属于 User 的任何字段,实际上您不应该这样做,而是让 UserCreationForm 处理它,因为那里对密码进行了一些特殊处理。

    这样做,在您的表单类保存方法中:

    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
    

    这将产生 TeacherRegistrationForm,它是 UserCreationForm 的一个子类,而后者又是 ModelForm 的一个子类。它将做 ModelForm 应该做的事情,即当你将自己保存到数据库(用户表)中调用它的保存方法。所以这一切都为你完成了。然后,您只需处理为其他模型添加到表单中的额外字段。

    注意我使用模型save() 方法而不是使用create(),在这种情况下完成相同的事情.. 但您可以稍后修改表单代码以允许相同的表单编辑现有模型而不是只需创建一个新的。如果您也希望我解释一下,请告诉我。

    【讨论】:

    • 我大部分理解你的意思。基本上因为 ModelForm 将处理所有默认字段,我不需要告诉它保存它们,因此不需要我的部分代码。当我来制作我的编辑页面时,使用 save() 将允许我更新用户?可以吗?
    • 没错,就是这样。 ModelForm save 方法将保存它所基于的模型中存在的任何字段(在本例中为User),您只需处理其他字段。至于更新与插入,为了进行更新,您必须将要更新的实例传递给 ModelForm 的构造函数。我现在正在使用手机,但我会在早上更新我的答案,以显示一个可以插入或更新的表单。
    【解决方案2】:

    尝试像这样编辑您的表单,

    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
    

    使用User.objects.create_user() 而不是objects.create

    我看不出将request 传递到保存方法中的意义。您可以删除该部分。 save 方法在执行form.save() 时被调用。另外,实际上不需要在表单保存方法中再次保存表单。

    【讨论】:

    • 在我的视图中出现错误“/users/register save() 的 TypeError 需要 1 个位置参数,但给出了 2 个”user, teacher_profile = form.save(request) 编辑:设法让它工作!感谢您的帮助
    • 不需要以自定义方式保存用户,因为 UserCreationForm 具有可以创建具有密码设置和验证的用户的逻辑
    • 这不是正确的做法。没有必要明确设置 first_name 或任何这些用户字段。
    【解决方案3】:

    不需要以自定义方式保存用户,您继承了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
    

    【讨论】:

      猜你喜欢
      • 2020-04-14
      • 2019-03-31
      • 1970-01-01
      • 2022-11-14
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      • 2015-03-22
      • 1970-01-01
      相关资源
      最近更新 更多