表单(Form) 在Web开发中是一个必不可少的组件,它允许用户填写信息并把这些信息提交给服务器进行处理。通过 Django 自带的 Form 组件,可以轻松地创建表单及表单处理逻辑。其中,form_valid_json 是一个特别实用的函数。
form_valid_json() 函数是 Django 中用于处理表单数据的一个函数。所谓表单数据,就是用户通过表单提交给服务器的数据。经过 Django 的数据处理,表单数据将被打包成一个字典对象,并传递给 form_valid_json() 函数进行处理。
form_valid_json() 函数的作用是将请求提交的表单数据经过有效性验证之后,将数据以及验证结果以 JSON 格式输出。
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 提交,则直接返回父类的函数处理结果。
假设有个网站需要用户填写一份调查表,并将调查表的数据记录在数据库中。这里我们来实现连同数据库入库的表单预处理。
模型类:
# 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 页面。
我们接下来结合一个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">×</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以及错误信息。
form_valid_json() 内部使用的是 Django 内置的 JsonResponse 类。JsonResponse 类允许我们将 Python 对象(如字典)转换成 Json 的格式,并自动设置响应类型等元数据。当 JsonResponse 类接收到一个字典对象时,它默认使用 application/json 类型进行响应。
最后,需要注意的是,使用 form_valid_json() 函数前,我们需要确保表单数据已经通过有效性验证。这通常通过调用表单类的 is_valid() 方法实现。有效性验证确保了表单数据的准确性和安全性,避免了因数据不完整或者不合法造成的安全隐患。
本文链接:http://task.lmcjl.com/news/16153.html