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

  • Post category:Python

form_invalid()是Django中form表单校验不通过时触发的函数,它的作用是处理校验不通过的情况。在该函数中,可以自定义返回的内容信息,如错误提示信息等。

form_invalid()函数位于Django内置的FormMixin中,通常会与其他类混合使用,如CreateView、UpdateView等。

以下是form_invalid()函数的使用方法:

from django.views.generic.edit import FormMixin
from django.views.generic import TemplateView

class MyFormView(FormMixin, TemplateView):
    form_class = MyFormClass    # 表单类
    template_name = 'my_template.html'   # 模板文件

    def get(self, request, *args, **kwargs):
        form = self.get_form()
        return self.render_to_response({'form': form})

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def form_invalid(self, form):
        # 处理校验不通过的情况,返回错误信息到模板页面
        context = self.get_context_data(form=form)
        return self.render_to_response(context)

    def form_valid(self, form):
        # 处理校验通过的情况
        # TODO: do something
        pass

在该例中,MyFormView是一个自定义的表单视图类,通过混合FormMixinTemplateView两个类实现。form_class属性指定了该表单对应的表单类。在get()函数中,预先渲染表单并返回渲染后的数据;在post()函数中,首先按照表单类中定义的规则校验表单,如果校验通过,则调用form_valid()函数处理校验通过的情况;否则,调用form_invalid()函数处理校验不通过的情况。

以下提供两个使用实例:

实例1:用户登录

from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate, login
from django.views.generic.edit import FormMixin, View

class LoginView(FormMixin, View):
    form_class = AuthenticationForm
    template_name = 'login.html'

    def get(self, request, *args, **kwargs):
        form = self.get_form()
        return self.render_to_response({'form': form})

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            user = authenticate(request, username=username, password=password)
            if user is not None:
                login(request, user)
                return redirect('home')
        return self.form_invalid(form)

    def form_invalid(self, form):
        context = self.get_context_data(form=form)
        context['message'] = u'用户名或密码错误'
        return self.render_to_response(context)

在该例中,LoginView是一个自定义的登录视图类,通过混合FormMixinView两个类实现。form_class属性指定了该表单对应的表单类为AuthenticationForm,即Django内置的用户认证表单。在post()函数中,处理用户登录请求,通过校验表单的方式判断用户名和密码是否正确。如果用户名和密码正确,则调用login()函数实现当前用户登录;否则,调用form_invalid()函数处理校验不通过的情况,返回错误提示信息到登录页面。

实例2:添加评论

from django.urls import reverse_lazy
from django.views.generic.edit import CreateView
from .models import Post, Comment
from .forms import CommentForm

class PostDetailView(CreateView):
    model = Post
    template_name = 'post_detail.html'
    form_class = CommentForm

    def get_success_url(self):
        return reverse_lazy('post_detail', kwargs={'pk': self.object.pk})

    def get_context_data(self, **kwargs):
        context = super(PostDetailView, self).get_context_data(**kwargs)
        context['comments'] = self.object.comment_set.all()
        return context

    def form_valid(self, form):
        self.object = self.get_object()
        form.instance.post = self.object
        form.save()
        return super(PostDetailView, self).form_valid(form)

    def form_invalid(self, form):
        context = self.get_context_data()
        context['form'] = form
        context['comments'] = self.object.comment_set.all()
        return self.render_to_response(context)

在该例中,PostDetailView是一个自定义的帖子详情视图类,该类展示了一篇帖子的详细内容,并可以添加评论。在form_class属性中,指定评论所对应的表单类为CommentForm。在form_valid()函数中,处理表单提交请求,将评论内容与对应的帖子关联起来,通过调用form.save()函数实现评论信息的保存。如果校验不通过,则调用form_invalid()函数处理校验不通过的情况,返回错误提示信息到对应的页面。