【问题标题】:can't pass 'user' parameter to ChangePasswordForm in django无法将“用户”参数传递给 django 中的 ChangePasswordForm
【发布时间】:2015-12-30 09:59:33
【问题描述】:

美好的一天!

我正在使用基于类的视图学习 Django (1.8)。 Django 本身提供了一个身份验证模块,可以更改用户的密码。在使用 Django 的 PasswordChangeForm(它扩展了 Django 的 SetPasswordForm)时,我偶然发现了以下错误:

init() 缺少 1 个必需的位置参数:'user'

当我查看 SetPasswordForm 类时,我可以看到它需要一个用户对象作为参数。

def __init__(self, user, *args, **kwargs):
    self.user = user
    super(SetPasswordForm, self).__init__(*args, **kwargs)


我最初做了什么?
首先,在我看来,我只是分配了 Django 的 PasswordChangeForm:

class ChangePassword(LoginRequiredMixin, FormView):
    template_name = 'users/reset_password.html'
    form_class = PasswordChangeForm

这当然导致了错误,因为没有提供用户对象。

那么我尝试过什么来解决这个问题?

尝试一:继承自 PasswordChangeForm 并添加 init 方法。
由于 PasswordChangeForm 没有 init 方法,我创建了一个名为 MyPasswordChangeForm 的新表单类,它继承自 PasswordChangeForm 并添加了 init:

class MyPasswordChangeForm(PasswordChangeForm):
    def __init__(self, request, *args, **kwargs):
        super(MyPasswordChangeForm, self).__init__(request.user, *args, **kwargs)

预期结果:MyPasswordChangeForm->从 PasswordChangeForm 继承并添加 init->super init->在 SetPasswordForm 中执行 init
实际结果:super正在调用LoginRequiredMixin:

init() 缺少 1 个必需的位置参数:“请求”
stack-tr l:80 return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)

尝试“二”:小改动 将 super->MyPasswordChangeFrom 更改为 super->PasswordChangeForm

尝试三:使用mixin,但不幸的是得到了与上面相同的结果。

尝试四:尚未完成,但会是最后的选择吗?但是必须有办法尽可能多地使用django的表单。

所以我的问题是…… 有人可以就我如何通过 Django 的 PasswordChangeForm 将(经过身份验证的)用户对象传递给 Django 的 SetPasswordForm 给出一个提示或小解释,这样我就可以尽可能多地使用当前存在的表单。

提前致谢!

【问题讨论】:

    标签: django forms inheritance django-class-based-views


    【解决方案1】:

    request 在初始化时默认不会发送到FormView。你必须以某种方式把它偷偷溜进去。

    根据您的尝试#1,一个很好的方法是覆盖FormView 中的get_form_kwargs() 方法,并将request 添加为super 已经提供的字典的键。然后,使用MyPasswordChangeForm__init__中的kwargs得到request

    基本上,你会做这样的事情:

    class ChangePassword(LoginRequiredMixin, FormView):
        template_name = 'users/reset_password.html'
        form_class = PasswordChangeForm
    
        def get_form_kwargs(self, **kwargs):
            data = super(ChangePassword, self).get_form_kwargs(**kwargs)
            data['request'] = self.request
            return data
    

    然后,在表单的 init 中:

    def __init__(self, *args, **kwargs):
        request = kwargs.pop("request") # it's best you pop request, so that you don't get any complains for a parent that checks what kwargs it gets
        super(MyPasswordChangeForm, self).__init__(request.user, *args, **kwargs)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 2015-11-11
      • 2020-05-15
      • 2015-04-18
      • 1970-01-01
      相关资源
      最近更新 更多