Интересует get_form_kwargs в FormView

Недавно у меня возникли проблемы с 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://stackoverflow.com/questions/13383381/show-message-after-password-change
# 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'.

Может ли кто-нибудь объяснить это мне?

Спасибо за помощь :)


person a_technicolor_skye    schedule 04.09.2013    source источник


Ответы (1)


Метод get_form_kwargs вернет словарь с kwargs, которые будут переданы в __init__ вашей формы. Теперь, если у вас есть форма, которая ожидает kwarg с именем user и передает ей kwarg с именем request, она выдаст сообщение об ошибке, которое вы видите. Если вы хотите передать request вместо user (это то, что я обычно делаю, поскольку запрос содержит пользователя), вы должны определить свой класс формы следующим образом:

class RequestForm(forms.Form):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(RequestForm, self).__init__(*args, **kwargs)
person Serafeim    schedule 04.09.2013
comment
Не могли бы вы сказать мне, как моя форма ожидает request от моего кода, поскольку я мог бы просто определить его как: def get_form_kwargs(self): kwargs = super(InternalResetPasswordView, self).get_form_kwargs() kwargs['request'] = self.request return kwargs. Извините за форматирование, не могу заставить работать разрывы строк. - person a_technicolor_skye; 04.09.2013
comment
С помощью метода def get_form-kwargs(self) вы не определяете форму, вы просто определяете, какие kwargs будут передавать ваше представление в форму! Форма django ожидает определенных kwargs. Если вы попытаетесь передать ему что-то неожиданное, он будет жаловаться. Вот почему вам нужно вызвать kwargs.pop(), чтобы удалить запрос, который вы хотите использовать в своей реализации формы, перед вызовом super().__init___. - person Serafeim; 04.09.2013
comment
Поскольку FormView создает экземпляр формы, почему он не принимает request в качестве аргумента? Нубский вопрос здесь ›.‹ - person a_technicolor_skye; 04.09.2013
comment
В своем InternalResetPasswordView вы передаете form_class = forms.InternalPasswordResetForm. Таким образом, вашему FormView нужно будет создать экземпляр InternalPasswordResetForm и передать __init___ результат метода get_form_kwargs()! Таким образом, в вашем InternalPasswordResetForm вы должны удалить все дополнительные аргументы из словаря kwargs, прежде чем передавать его в super.__init__ ! Ошибка не в вашей реализации FormView, а в вашей Form! - person Serafeim; 04.09.2013