Форма представления на основе классов не является ни валидной, ни невалидной (Django)

Я новичок в Django Class Based Views и не могу заставить свою форму пройти ни через form_valid(), ни через form_invalid().

Я взял большую часть этого кода из модуля Django allauth, поэтому я расширяю некоторые миксины (AjaxCapableProcessFormViewMixin & LogoutFunctionalityMixin), которые я плохо знаю.

Эта форма предназначена для того, чтобы пользователи могли изменить свой пароль после получения электронного письма. В текущем виде пользователи могут изменить пароль, но поскольку функция form_valid() никогда не срабатывает, они не перенаправляются на URL успеха, как предполагалось. Вместо этого смена пароля регистрируется, но пользователи остаются на той же странице.

Функции dispatch(), get_form_kwargs() & get_form_class() срабатывают и ведут себя так, как должны. Тем не менее, мне неясно, почему они выполняются именно в таком порядке (сначала срабатывает dispatch(), затем get_form_class() и, наконец, get_form_kwargs(). Я полагаю, что они неявно имеют порядок, представленный в этой документации: https://ccbv.co.uk/projects/Django/4.0/django.views.generic.edit/FormView/)

Мне не хватает интуиции в том, как это работает, поэтому я не знаю, есть ли способ перенаправить на URL успеха без прохождения через form_valid(), потому что это также решило бы мою проблему.

Как указано в заголовке, ни form_valid(), ни form_invalid() не срабатывают после ввода нового пароля. Последний выполненный бит кода - это return kwargs из функции get_form_kwargs().

Вот мой код:

class PasswordResetFromKeyView(AjaxCapableProcessFormViewMixin, LogoutFunctionalityMixin, FormView):
    template_name = "account/password_reset_from_key." + app_settings.TEMPLATE_EXTENSION
    form_class = ResetPasswordKeyForm
    success_url = '/'
    reset_url_key = "set-password"

    def get_form_class(self):
        return get_form_class(
            app_settings.FORMS, "reset_password_from_key", self.form_class
        )

    def dispatch(self, request, uuid, **kwargs):
        self.request = request

        token = get_object_or_404(ResetToken, token=uuid)

        if token.redeemed == False:
            self.reset_user = token.client
            self.token = token
            response = self.render_to_response(self.get_context_data(token_fail=False))
        else:
            return super(PasswordResetFromKeyView, self).dispatch(
                    request, uuid, **kwargs
                )
        return response


    def get_form_kwargs(self, **kwargs):
        kwargs = super(PasswordResetFromKeyView, self).get_form_kwargs(**kwargs)
        kwargs["user"] = self.reset_user
        if len(kwargs) > 3:
            try:
                if kwargs['data']['password1'] == kwargs['data']['password2']:
                    self.reset_user.set_password(kwargs['data']['password1'])
                    self.reset_user.save()
                    self.token.redeemed = True
                    self.token.date_redeemed = datetime.now()
                    self.token.save()
                    perform_login(
                        self.request,
                        self.reset_user,
                        email_verification=app_settings.EMAIL_VERIFICATION,
                    )
                else:
                    pass
                    ##passwords dont match
            except:
                ##couldnt change the password
                pass
        return kwargs

    def form_valid(self, form, **kwargs):
        form.save()
        return super(PasswordResetFromKeyView, self).form_valid(form)

    def form_invalid(self, form):
        response = super().form_invalid(form)
        if self.request.accepts('text/html'):
            return response
        else:
            return JsonResponse(form.errors, status=400)

Спасибо всем за помощь!

Если оба метода не срабатывают, это означает, что ваш requests.method никогда не будет 'POST'.

Класс FormView вызывает эти два метода, только если post.method == 'POST':

# code from django.views.generic.edit
...
def post(self, request, *args, **kwargs):
    """
    Handle POST requests: instantiate a form instance with the passed
    POST variables and then check if it's valid.
    """
    form = self.get_form()
    if form.is_valid():
        return self.form_valid(form)
    else:
        return self.form_invalid(form)

Кстати в dispatch, если token.redeemed == False вы должны вернуть self.form_invalid().

Вернуться на верх