在业务开发中,表单验证是较为重要的一环,经过验证后的数据才能存储进数据库。其中,表单验证不仅包括对恶意数据的检测,还包括了对业务逻辑上的一些检测。
之前笔者对Django Form的源码进行了一些浅显的分析,经过一段时间的使用以后,积累了一些使用的经验因此写下这篇博客来备忘。
关于Django Form源码分析的传送门如下:
Django Form源码分析之BaseForm验证逻辑
Django Form源码分析之Field验证逻辑
使用Django Form进行表单验证
一般来说,笔者在Django CBV中使用Django Form比较喜欢如下的代码流程:
class ExampleView(View):
def get(self, request, *args, **)
form = GetDataForm(data=request.GET)
if form.is_valid():
# run business logic code
else:
# form.error_detail()返回包含数据错误的字典
return JsonResponse(form.error_detail())
def post(self, request, *args, **)
form = PostDataForm(data=request.POST)
if form.is_valid():
# run business logic code
else:
# form.error_detail()返回包含数据错误的字典,自行定义
return JsonResponse(form.error_detail())
这个流程非常简单清晰,将根据不同HTTP方法传输过来的数据作为参数实例化一个DataForm,调用is_valid方法验证数据,如果数据验证准确,则可以运行业务逻辑,如果数据验证错误,需要以JSON格式返回错误信息给前端。
PS:笔者比较倾向于将业务逻辑绑定在具体的Form上面,作为一个Form的方法来实现,因为业务逻辑是跟传输过来的数据是紧耦合的,在业务逻辑中可以直接通过self.cleaned_data直接获得相关数据。在StackOverFlow还有关于业务逻辑代码安排在哪里的讨论,有兴趣的同学可以去看一下:Separation of business logic and data access in django
构造业务的BaseForm
在开发的时候,后端通常需要给出前端当表单验证错误的时候错误信息的数据格式。
举个例子,假设有一个用户表单对提交的两个数据进行验证:
# Form.py
from django import forms
class UserForm(forms.Form):
name = forms.CharField()
age = forms.IntegerField()
然后返回的JSON数据格式要求如下:
# Json Data Format
{
"status": 2,
"msg": "form validate error",
"data": {
'name': ['This field is required.'],
'age': ['Enter a number.']
}
}
很显然,Form.errors字典不能满足这种数据格式的需求。
所以需要开发者自行定义一个作为基类的BaseForm,并在BaseForm中定义error_detail方法,