无法通过用户' django

时间:2015-12-30 09:59:33

标签: django forms inheritance class-based-views

美好的一天SO!

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

  

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

当我看一下SetPasswordForm类时,我可以看到它需要一个user-object作为参数。

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并在SetPasswordForm中添加init-> super init->执行init 实际结果:super正在调用LoginRequiredMixin:

  

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

尝试'两次' 次要变更 将超级> MyPasswordChangeFrom更改为super-> PasswordChangeForm

尝试三:使用mixin,但遗憾的是上面的结果相同。

尝试四:尚未完成此操作,但这是最终的选择吗?但必须有一种方法尽可能多地使用django的形式。

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

提前致谢!

1 个答案:

答案 0 :(得分:5)

初始化时,

request默认不会发送到FormView。你不得不以某种方式偷偷溜进去。

根据您的尝试#1,执行此操作的一种好方法是覆盖get_form_kwargs()中的方法FormView,并添加request作为该字典的关键字' s super已经提供了。然后,使用kwargs MyPasswordChangeForm中的__init__获取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

然后,在你的表单初始化中

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)