FormView中的get_form_kwargs是什么?

27

最近我在使用FormView时遇到了问题,发现解决方法是使用get_form_kwargs。

这是我的代码:

class InternalResetPasswordView(FormView):

template_name = 'reset_password.html'
form_class = forms.InternalPasswordResetForm

# success_message = "Password was reset successfully"

# To get request object
# http://notesondjango.wordpress.com/2012/12/18/modelform-formview-and-the-request-object/
# https://dev59.com/6GrXa4cB1Zd3GeqPDdqD
# http://pydanny.com/simple-django-email-form-using-cbv.html
# http://bubuzzz.wordpress.com/2012/05/01/class-based-generic-views-in-django-a-simple-sample/
def get_form_kwargs(self):
    kwargs = super(InternalResetPasswordView, self).get_form_kwargs()
    kwargs['user'] = self.request.user
    return kwargs

def get_success_url(self):
    return reverse('user-detail', kwargs={'pk': self.request.user.id})

@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
    return super(InternalResetPasswordView, self).dispatch(*args, **kwargs)   

'''
def get_context_data(self, **kwargs):

    context = super(InternalResetPasswordView, self).get_context_data(**kwargs)
    context['InternalPasswordResetForm'] = context.get('form')

    return context


def get_form_kwargs(self):
    kwargs = super(InternalResetPasswordView, self).get_form_kwargs()
    kwargs['request'] = self.request
    return kwargs

'''
# self.request.user method obtained from
# https://docs.djangoproject.com/en/dev/topics/class-based-views/generic-editing/
def form_valid(self, form):
    current_password = form.cleaned_data['old_password']
    new_password =  form.cleaned_data['new_password1']
    confirm_new_password = form.cleaned_data['new_password2']
    user = self.request.user
    if user.check_password(current_password) and new_password == confirm_new_password:
        user.set_password(new_password)
        user.save()
        # form.valid() redirects to get_success_url
    return super(InternalResetPasswordView, self).form_valid(form)

在查看这篇文章后,我仍然不明白为什么要使用get_form_kwargs,以及为什么在这种情况下使用self.request而不是self.request.user会给出__init__() got an unexpected keyword argument 'request'

有人能解释一下吗?

感谢所有的帮助 :)

1个回答

35

get_form_kwargs方法将返回一个字典,其中包含将传递给表单的__init__的kwargs。如果您有一个期望名为user的kwarg的表单,并传递一个名为request的kwarg,则会出现错误。如果您想传递request而不是user(这是我通常做的,因为请求包含用户),则应该像这样定义表单类:

class RequestForm(forms.Form):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(RequestForm, self).__init__(*args, **kwargs)

你能告诉我我的表单如何从代码中期望“请求(request)”,因为我可以定义它如下: def get_form_kwargs(self): kwargs = super(InternalResetPasswordView, self).get_form_kwargs() kwargs['request'] = self.request return kwargs。 抱歉格式有些混乱,无法换行。 - a_technicolor_skye
4
使用def get_form-kwargs(self)方法,你并没有定义一个Form,而是定义了哪些kwargs将被传递给你的View到Form!Django Form期望特定的kwargs。如果你试图传递不被期望的内容,它会报错。这就是为什么在调用super().__init___之前,你需要调用kwargs.pop()来删除你想在Form实现中使用的request参数。 - Serafeim
既然FormView实例化了一个表单,那为什么它不需要将“request”作为参数呢?这是一个新手问题 >.< - a_technicolor_skye
1
在你的InternalResetPasswordView中,你正在传递一个form_class = forms.InternalPasswordResetForm。因此,你的FormView将需要实例化一个InternalPasswordResetForm实例,并将其传递给该方法的__init___的get_form_kwargs()方法的结果!因此,在你的InternalPasswordResetForm中,你必须在将其传递给super.__init__之前从kwargs字典中删除任何额外的参数!错误不在于你的FormView实现,而在于你的Form - Serafeim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接