无法将 'user' 参数传递给 Django 中的 ChangePasswordForm
can't pass 'user' parameter to ChangePasswordForm in django
美好的一天!
我正在使用基于 class 的视图学习 Django (1.8)。 Django 本身提供了一个可以更改用户密码的身份验证模块。在使用 Django 的 PasswordChangeForm(它扩展了 Django 的 SetPasswordForm)时,我偶然发现了以下错误:
init() missing 1 required positional argument: 'user'
当我查看 SetPasswordForm class 时,我发现它需要一个用户对象作为参数。
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 的新表单 class,它继承自 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() missing 1 required positional argument: 'request'
stack-tr l:80 return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
尝试'two': 小改动
将 super->MyPasswordChangeFrom 更改为 super->PasswordChangeForm
尝试三:使用mixin,不幸的是结果和上面一样。
尝试四:还没有做这个,但会是最后的选择吗?但是必须有一种方法可以尽可能多地使用django的表单。
所以我的问题是...
有人可以就如何通过 Django 的 PasswordChangeForm 将(经过身份验证的)用户对象传递给 Django 的 SetPasswordForm 给出提示或小的解释,这样我就可以尽可能多地使用当前存在的表单。
提前致谢!
默认情况下 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
然后,在您的表单初始化中:
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)
美好的一天!
我正在使用基于 class 的视图学习 Django (1.8)。 Django 本身提供了一个可以更改用户密码的身份验证模块。在使用 Django 的 PasswordChangeForm(它扩展了 Django 的 SetPasswordForm)时,我偶然发现了以下错误:
init() missing 1 required positional argument: 'user'
当我查看 SetPasswordForm class 时,我发现它需要一个用户对象作为参数。
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 的新表单 class,它继承自 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() missing 1 required positional argument: 'request'
stack-tr l:80 return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
尝试'two': 小改动 将 super->MyPasswordChangeFrom 更改为 super->PasswordChangeForm
尝试三:使用mixin,不幸的是结果和上面一样。
尝试四:还没有做这个,但会是最后的选择吗?但是必须有一种方法可以尽可能多地使用django的表单。
所以我的问题是... 有人可以就如何通过 Django 的 PasswordChangeForm 将(经过身份验证的)用户对象传递给 Django 的 SetPasswordForm 给出提示或小的解释,这样我就可以尽可能多地使用当前存在的表单。
提前致谢!
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
然后,在您的表单初始化中:
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)