美好的一天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提供一个提示或小解释,因此我可以尽可能多地使用当前存在的表单。
提前致谢!
答案 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)