详解Django的 form_valid_json() 函数:返回表单验证成功后的 JSON 数据

yizhihongxing

表单(Form) 在Web开发中是一个必不可少的组件,它允许用户填写信息并把这些信息提交给服务器进行处理。通过 Django 自带的 Form 组件,可以轻松地创建表单及表单处理逻辑。其中,form_valid_json 是一个特别实用的函数。

1. form_valid_json()函数的作用

form_valid_json() 函数是 Django 中用于处理表单数据的一个函数。所谓表单数据,就是用户通过表单提交给服务器的数据。经过 Django 的数据处理,表单数据将被打包成一个字典对象,并传递给 form_valid_json() 函数进行处理。

form_valid_json() 函数的作用是将请求提交的表单数据经过有效性验证之后,将数据以及验证结果以 JSON 格式输出。

2. form_valid_json()函数的使用方法

2.1 重写form_valid()函数

form_valid_json() 是一个被定义在 FormView 中的函数,因此在使用时需要对该 View 进行继承。具体而言,我们需要继承 FormView,并在该 View 中重写 form_valid() 函数。在重写 form_valid() 函数时,我们需要调用 form_valid_json() 函数,并将返回结果进行输出。

下面是一个示例代码:

from django.views.generic.edit import FormView
from django.http import JsonResponse
from myapp.forms import MyForm

class MyFormView(FormView):
    form_class = MyForm
    template_name = 'my_form.html'
    success_url = '/thanks/'

    def form_valid(self, form):
        response = super(MyFormView, self).form_valid(form)
        if self.request.is_ajax():
            return JsonResponse(form.cleaned_data)
        else:
            return response

其中,MyFormView 继承自 FormView,它指定了表单类 MyForm 以及模板 my_form.html。当表单提交成功时,会跳转到 thanks 页面。form_valid 函数首先调用父类实现的 form_valid 函数来处理表单,然后判断请求是否是 Ajax 提交,如果是则调用 form_valid_json() 函数将表单数据打包成Json格式输出。若不是 Ajax 提交,则直接返回父类的函数处理结果。

2.2 实例1

假设有个网站需要用户填写一份调查表,并将调查表的数据记录在数据库中。这里我们来实现连同数据库入库的表单预处理。

模型类:

# myapp/models.py
from django.db import models

class Survey(models.Model):
    name = models.CharField(max_length=200)
    gender = models.CharField(max_length=10)
    age = models.IntegerField(default=0)
    occupation = models.CharField(max_length=100)

    def __str__(self):
        return self.name

表单类:

# myapp/forms.py
from django import forms
from django.forms import ModelForm
from myapp.models import Survey

class SurveyForm(ModelForm):
    class Meta:
        model = Survey
        fields = ['name', 'gender', 'age', 'occupation']

视图函数:

# myapp/views.py
from django.views.generic.edit import FormView
from django.http import JsonResponse

class SurveyFormView(FormView):
    template_name = 'survey_form.html'
    form_class = SurveyForm
    success_url = '/thanks/'

    def form_valid(self, form):
        response = super(SurveyFormView, self).form_valid(form)
        if self.request.is_ajax():
            survey = form.save()
            return JsonResponse(form.cleaned_data)
        else:
            return response

在表单提交成功后,将表单数据保存到Survey模型类对应的数据库中。如果请求为Ajax 请求,那么Json 化输出表单数据,否则跳转到 success_url 页面。

2.3 实例2

我们接下来结合一个CSS框架—Bootstrap,来展示在通过一个模态框表单作为一个Post表单提交数据的Ajax/Json化输出。

模型:

# myapp/models.py
from django.db import models

class Contact(models.Model):
    name = models.CharField(max_length=50)
    age = models.IntegerField()
    email = models.EmailField()
    content = models.TextField()

    def __str__(self):
        return self.name

表单:

# myapp/forms.py
from django import forms
from myapp.models import Contact

class ContactForm(forms.ModelForm):
    class Meta:
        model = Contact
        fields = ('name', 'email', 'age', 'content')
        widgets = {'content': forms.Textarea({'cols': 20, 'rows': 5})} # 优化content的text区域

模板:

<!-- myapp/index.html -->
{% extends "base.html" %}
{% load static %}
{% block content %}
    <div class="container">
        <h1>Contact Us</h1>
        <hr>
        <button type="button" id="btn_contact" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#ContactModal">Contact Us</button>
        <br><br><br><br><br><br><br><br>
    </div>
    <!-- Modal -->
    <div class="modal fade" id="ContactModal" tabindex="-1" role="dialog" aria-labelledby="ContactModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content">
                <div class="modal-header bg-primary text-white">
                    <h5 class="modal-title" id="ContactModalLabel">Contact us </h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <form method="post" nctype="multipart/form-data" id="contact_form">
                    {% csrf_token %}
                    <div class="modal-body">
                        <div class="form-group row">
                            <div class="col-md-2">
                                <label for="{{ form.name.id_for_label }}" class="col-form-label">{{ form.name.label }}:</label>
                            </div>
                            <div class="col-md-10">
                                {{ form.name }}
                                <div class="invalid-feedback"></div>
                            </div>
                        </div>
                        <div class="form-group row">
                            <div class="col-md-2">
                                <label for="{{ form.email.id_for_label }}" class="col-form-label">{{ form.email.label }}:</label>
                            </div>
                            <div class="col-md-10">
                                {{ form.email }}
                                <div class="invalid-feedback"></div>
                            </div>
                        </div>
                        <div class="form-group row">
                            <div class="col-md-2">
                                <label for="{{ form.age.id_for_label }}" class="col-form-label">{{ form.age.label }}:</label>
                            </div>
                            <div class="col-md-10">
                                {{ form.age }}
                                <div class="invalid-feedback"></div>
                            </div>
                        </div>
                        <div class="form-group row">
                            <div class="col-md-2">
                                <label for="{{ form.content.id_for_label }}" class="col-form-label">{{ form.content.label }}:</label>
                            </div>
                            <div class="col-md-10">
                                {{ form.content }}
                                <div class="invalid-feedback"></div>
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="submit" class="btn btn-primary btn-lg">Submit</button>
                        <button type="button" class="btn btn-secondary btn-lg" data-dismiss="modal">Close</button>
                    </div>
                </form>
            </div>
        </div>
    </div>

<script>
    $(function () {
        $("#contact_form").submit(function (e) {
            e.preventDefault();
            $('#btn_contact').text('Submitting...').prop('disabled', true); // 从提交按钮变为提交中...
            $('.invalid-feedback').remove(); //...并且删除所有可能的错误信息
            $.ajax({
                url: "{% url 'ajax_contact_us' %}",
                type: "POST",
                data: $('#contact_form').serialize(),
                dataType: "json",
                success: function (response) {
                    console.log(response);
                    $('#ContactModal').modal('hide'); // 关闭模态框
                    $('#btn_contact').text('Submitted').prop('disabled', false); //提交按钮重置
                    alert('Your message has been sent!'); // 发送完毕,提示用户信息已发送。
                },
                error: function (response) {
                    $('button[type="submit"]').text('Submit').prop('disabled', false); //还原提交按钮状态
                    console.log(response);
                    var errors = response.responseJSON.errors;
                    $.each(errors, function (key, value) {
                        $("#" + key).addClass("is-invalid").after("<div class='invalid-feedback'>" + value + "</div>");
                    });
                }
            });
        });
    });
</script>
{% endblock %}

视图函数:

# myapp/views.py
def ajax_contact_us(request):
    if request.method == 'POST' and request.is_ajax():
        form = ContactForm(request.POST)
        if form.is_valid():
            response = {
                'message': 'Your message has been sent!',
                'status': 'success'
            }
            return HttpResponse(json.dumps(response), content_type='application/json')
        else:
            response = {
                'status': 'error',
                'errors': json.loads(form.errors.as_json()),
            }
            return JsonResponse(response, status=400)

在模板中创建模态框,通过Ajax提交表单,并输出Json串。如果Ajax请求为非法请求,则返回状态码400以及错误信息。

3. 其他

form_valid_json() 内部使用的是 Django 内置的 JsonResponse 类。JsonResponse 类允许我们将 Python 对象(如字典)转换成 Json 的格式,并自动设置响应类型等元数据。当 JsonResponse 类接收到一个字典对象时,它默认使用 application/json 类型进行响应。

最后,需要注意的是,使用 form_valid_json() 函数前,我们需要确保表单数据已经通过有效性验证。这通常通过调用表单类的 is_valid() 方法实现。有效性验证确保了表单数据的准确性和安全性,避免了因数据不完整或者不合法造成的安全隐患。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Django的 form_valid_json() 函数:返回表单验证成功后的 JSON 数据 - Python技术站

(0)
上一篇 2023年3月23日
下一篇 2023年3月23日

相关文章

  • 详解Django的 paginate_orphans() 函数:指定一页最少显示的对象数量

    Django的paginate_orphans()函数详解 paginate_orphans()函数是Django框架中pagination(分页)模块的一部分。其作用是用来确定在一个分页显示中的一页中最少要显示的记录数量。当一页中只有“孤儿”记录时,可以将它们作为上一页的最后一页来显示,以免摆在一页中的孤儿记录过少而显得过于孤立。 使用方法: class …

    Django函数大全 2023年3月23日
    00
  • 详解Django的 put() 函数:处理 PUT 请求

    Django中put()函数的作用与使用方法 put()函数是Django中HTTP协议中的PUT方法的处理方式。PUT方法是一种用于将更新请求发送到Web服务器的HTTP方法。put()函数通过将HTTP请求的主体内容解析为Python对象来解析put请求。 使用方法 使用put()函数的前提是 Django 的中间件 django.middleware.…

    Django函数大全 2023年3月23日
    00
  • 详解Django的 csrf_protect() 函数:装饰器,保护跨站请求伪造攻击

    下面我来详细讲解Django中csrf_protect()函数的作用和使用方法。 一、作用 Django本身具有一种防止跨站请求伪造(Cross Site Request Forgery, CSRF)攻击的机制,即CSRFToken机制。CSRFToken机制可以有效地防止一个站点被另一个站点伪造数据提交的攻击。但是,在一些特殊情况下,比如提交表单的数据不是…

    Django函数大全 2023年3月23日
    00
  • 详解Django的 get_form() 函数:获取视图所使用的表单实例

    下面是关于 Django 的 get_form() 函数的详细讲解。 1. get_form() 函数的作用 get_form() 是 Django 中一个非常重要的函数,其作用是返回一个表单实例,在视图函数中常常用于修改或者添加数据时,使用不同类型的表单进行数据的处理。 2. get_form() 函数的使用方法 通常情况下,get_form() 函数需要…

    Django函数大全 2023年3月23日
    00
  • 详解Django的 render() 函数:渲染模板

    Django的render()函数介绍 在Django中,render()函数是一个非常常用的函数。它的主要作用是将数据渲染到一个指定的模板中(一般是HTML文件),然后将渲染后的页面返回给浏览器。这个函数会自动的将我们通过视图函数传递进来的数据和模板进行整合,并生成HTML页面。render()函数的基本语法如下: render(request, temp…

    Django函数大全 2023年3月23日
    00
  • 详解Django的 clean() 函数:定义表单字段的清理行为

    Django clean()函数的作用与使用方法攻略 在 Django 中,clean() 函数是一个非常有用的方法,可以帮助我们校验表单提交的数据并返回经过校验后的数据。 作用 clean() 函数作用是在 Django Form 表单数据进行提交前进行校验,并将校验过后的数据返回。 校验的过程中,我们可以对该数据进行一些操作,比如格式化数据、消除不必要的…

    Django函数大全 2023年3月23日
    00
  • 详解Django的 create() 函数:创建对象

    当使用Django ORM作为后端数据库操作模块时,create()函数提供了方便的功能能够快速创建并保存一个模型实例。下面将详细讲解create()函数的作用和使用方法,同时提供两个实例进行说明。 作用 create()函数的作用是创建一个新的模型实例,并将其保存至数据库中。 使用方法 create()函数是一个类方法,可以在模型类上直接调用,使用方式如下…

    Django函数大全 2023年3月23日
    00
  • 详解Django的 form_valid() 函数:当表单验证成功时执行的操作

    Django中form_valid()函数的作用与使用方法 在Django中,视图函数中form_valid()函数是一个非常有用的函数。该函数主要用来在表单数据验证成功后处理表单数据。 1. 作用 form_valid()函数的作用是将表单验证成功后的数据传送给视图函数中的其他函数进行处理。借助form_valid()函数,我们可以将表单数据存储到数据库中…

    Django函数大全 2023年3月23日
    00
合作推广
合作推广
分享本页
返回顶部