详解Django的 form_invalidated() 函数:表单数据验证失败后的处理逻辑

  • Post category:Python

form_invalid()是Django中FormMixin提供的一个方法,用于处理表单验证不通过的情况。当表单验证失败时,Django会调用form_invalid()方法执行下面的一些操作:

  1. 利用form_class属性创建一个表单对象
  2. 根据表单对象,重定向向当前URL并附带上包括验证结果信息的GET参数
  3. 渲染模板

如果form_invalid()不被显式地实现,Django默认会返回一个HttpResponseBadRequest

form_invalid()方法中,我们可以添加自己的逻辑来处理特定的表单验证错误。每次在表单提交过程中,如果验证不成功就会调用form_invalid()方法。

下面给出两个实例:

实例一

我们先假设有一个简单的联系我们表单,表单有以下字段:姓名(Name),电子邮件(Email),主题(Subject)和消息正文(Message)。我们来看一下如何验证一封有效的邮件地址。

# views.py

from django.core.mail import send_mail
from django.urls import reverse_lazy
from django.views.generic.edit import FormView
from .forms import ContactForm

class ContactView(FormView):
    template_name = "contact.html"
    form_class = ContactForm
    success_url = reverse_lazy('contact_success')

    def form_valid(self, form):
        subject = form.cleaned_data['subject']
        message = form.cleaned_data['message']
        from_email = form.cleaned_data['from_email']
        send_mail(subject, message, from_email, ['your-email@example.com'], fail_silently=False)
        return super().form_valid(form)

    def form_invalid(self, form):
        form.add_error('from_email', 'Please enter valid email address.')
        return super().form_invalid(form)

在这个例子中,form_invalid()方法被用来添加邮件地址验证错误消息。如果邮件地址无效,表单将重新呈现,并且一个带着错误消息的form实例将被传递给模板。

<!-- contact.html -->

<form method="POST">
  {% csrf_token %}
  {{ form.as_p }}
  <input type="submit" value="Submit">
  {% if form.errors %}
    <p>Email address is invalid</p>
  {% endif %}
</form>

实例二

假设你想要在用户修改一个表单的时候,要求他们输入一个确认密码。可以在表单中添加一个confirm_password字段,然后在form_valid()方法中检查输入的密码和确认密码是否相等。如果不相等,则调用form_invalid()方法。

# views.py

from django.urls import reverse_lazy
from django.views.generic.edit import UpdateView
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from .models import UserProfile
from .forms import UserProfileForm

@method_decorator(login_required, name='dispatch')
class UserProfileUpdate(UpdateView):
    model = UserProfile
    form_class = UserProfileForm
    template_name = 'profile/update.html'
    success_url = reverse_lazy('profile:detail')

    def form_valid(self, form):
        if form.cleaned_data.get('password') != form.cleaned_data.get('confirm_password'):
            return self.form_invalid(form)
        return super().form_valid(form)

    def form_invalid(self, form):
        form.add_error('confirm_password', "Passwords don't match")
        return super().form_invalid(form)

在这个实例中,form_invalid()方法被用来添加表单密码确认错误消息,并重新呈现包含错误消息的表单。