详解Django的 get_failure_url() 函数:获取表单处理失败后的跳转 URL

  • Post category:Python

get_failure_url()函数是Django框架中一个针对表单类视图FormView所提供的方法,用来指明表单验证不通过时跳转的页面。

使用方法

在定义FormView时可以添加get_failure_url()方法,该方法返回一个URL字符串,表示表单验证不通过时要跳转的页面。以下是一个示例:

from django.urls import reverse_lazy
from django.views.generic.edit import FormView

from .models import MyModel
from .forms import MyForm

class MyFormView(FormView):
    template_name = 'my_template.html'
    form_class = MyForm
    success_url = reverse_lazy('my-success-view')

    def form_valid(self, form):
        # 数据验证通过时调用该方法,请求成功后跳转到 success_url 指定的页面
        MyModel.objects.create(**form.cleaned_data)
        return super().form_valid(form)

    def form_invalid(self, form):
        # 数据验证不通过时调用该方法,请求失败后跳转到 get_failure_url() 指定的页面
        return super().form_invalid(form)

    def get_failure_url(self):
        # 指明表单验证不通过时所跳转的页面
        return reverse_lazy('my-failure-view')

在上述示例中,get_failure_url()方法返回了一个URL字符串,指定了表单验证不通过时要跳转的页面。如果用户在填写表单时出现错误,Django将调用form_invalid()方法,该方法中将返回指定的页面。如果没有实现get_failure_url()方法,则会跳转到success_url指定的页面。

实例

示例一

假设我们有一个注册页面,包含用户名和密码两个输入框。其中,用户名必须不为空,密码必须超过6个字符。如果验证不通过,则需要在同一页中同时显示错误信息。以下是示例代码:

from django.urls import reverse_lazy
from django.views.generic.edit import FormView
from django import forms

class RegisterForm(forms.Form):
    username = forms.CharField(label='用户名')
    password = forms.CharField(label='密码', widget=forms.PasswordInput)

    def clean(self):
        cleaned_data = super().clean()
        username = cleaned_data.get('username', '').strip()
        password = cleaned_data.get('password', '').strip()
        if not username:
            self.add_error('username', '用户名不能为空')
        if len(password) < 6:
            self.add_error('password', '密码不能少于6个字符')
        return cleaned_data

class RegisterView(FormView):
    template_name = 'register.html'
    form_class = RegisterForm
    success_url = reverse_lazy('register-success')
    def form_valid(self, form):
        # 注册信息保存
        return super().form_valid(form)

    def get_failure_url(self):
        # 指定表单验证不通过时跳转的URL
        return reverse_lazy('register')

在上述示例中,RegisterForm用于验证表单数据的正确性,错误信息保存在form.errors属性中并被传递到模板文件。RegisterViewFormView的子类,并指定使用RegisterForm作为验证器。如果表单验证通过,则会调用form_valid()方法,并在成功后跳转到success_url指定的页面。如果表单验证不通过,则会调用form_invalid()方法,并在失败后跳转到get_failure_url()返回的页面。

示例二

假设我们有一个预约页面,只能在指定的工作时间段内预约。以下是示例代码:

from django.urls import reverse_lazy
from django.views.generic.edit import FormView
from django import forms
from datetime import datetime, time

class AppointmentForm(forms.Form):
    name = forms.CharField(label='姓名')
    time = forms.DateTimeField(label='预约时间')

    def clean(self):
        cleaned_data = super().clean()
        time = cleaned_data.get('time')
        if not time:
            return cleaned_data
        hour = time.time().hour
        if hour < 9 or hour > 17:
            raise forms.ValidationError('请在工作时间内预约')
        return cleaned_data

class AppointmentView(FormView):
    template_name = 'appointment.html'
    form_class = AppointmentForm
    success_url = reverse_lazy('appointment-success')
    def form_valid(self, form):
        # 处理表单数据
        return super().form_valid(form)

    def get_failure_url(self, cleaned_data):
        # 指定表单验证不通过时跳转的URL
        time = cleaned_data.get('time')
        if time:
            return reverse_lazy('appointment-time', args=(time.strftime('%Y-%m-%d %H:%M:%S'),))
        return reverse_lazy('appointment')

在上述示例中,AppointmentForm用于验证表单数据的正确性。如果输入的预约时间不在9:00-17:00范围内,则会抛出一个ValidationError异常,该异常的信息将会在页面上显示错误提示。AppointmentViewFormView的子类,用于处理预约表单提交。如果表单验证通过,则会调用form_valid()方法,并在成功后跳转到success_url指定的页面;如果表单验证不通过,则会调用form_invalid()方法,并在失败后跳转到get_failure_url()返回的页面。最后,在get_failure_url()中,我们检查表单中预约时间是否在工作时间内,如果不是,则按照约定的URL格式返回到一个由另一个视图处理的页面中,可以将预约时间作为参数传递。