在HTML页面或者请求接口时经常会使用到对参数的校验,django提供了form类和modelform两种用于对参数进行校验的类
下面例子是基于django前后端分离,后端进行参数校验
定义models.py ,定义Case用例表和CaseSet用例集合表
1 from django.db import models 2 3 # Create your models here. 4 class BaseModel(models.Model): 5 create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') 6 update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间') 7 is_delete = models.BooleanField(verbose_name='是否删除', default=False) 8 9 class Meta: 10 abstract = True #声明这个类只是用来继承的,不会创建这张表 11 12 class CaseSet(BaseModel):#用例集合和用例多对多关系 13 name = models.CharField(verbose_name='集合名称',max_length=60) 14 desc = models.CharField(verbose_name='集合描述',max_length=70) 15 class Meta: 16 db_table = 'case_set' 17 verbose_name = '用例集合表' 18 verbose_name_plural = verbose_name 19 20 def __str__(self): 21 return self.name 22 23 class Case(BaseModel): 24 title = models.CharField(verbose_name='用例标题',max_length=80,db_index=True,unique=True) 25 desc = models.CharField(verbose_name='用例描述',max_length=120) 26 method_choice = [ 27 [0,'get'], 28 [1,'post'], 29 [2,'put'], 30 [3,'delete'] 31 ] #枚举 32 method = models.SmallIntegerField(choices=method_choice,verbose_name='请求方式',default=0) 33 url = models.URLField(max_length=50,verbose_name='请求url') 34 params = models.TextField(verbose_name='请求参数') 35 run_count = models.IntegerField(verbose_name='运行次数',default=0,null=True,blank=True) 36 run_time = models.DateTimeField(verbose_name='运行时间',default=None,null=True,blank=True) 37 case_set = models.ManyToManyField(CaseSet,db_constraint=False,verbose_name='用例集合',null=True,blank=True) 38 39 class Meta: 40 db_table = 'case' 41 verbose_name = '用例表' 42 verbose_name_plural = verbose_name 43 44 def __str__(self): 45 return self.title
views.py
1.使用form校验入参
使用cvb方式定义CaseSet和CaseView类来返回用例集合和用例,定义CaseSetForm和CaseForm类分别校验case和caseset
1 from django.core.exceptions import ValidationError 2 from django.forms import model_to_dict 3 from django.http import JsonResponse 4 from django.shortcuts import render 5 from django.views import View 6 from django import forms 7 from . import models 8 9 10 #form 参数校验 11 class CaseForm(forms.Form):#校验参数满足条件,不满足条件时报错 12 '''校验请求参数''' 13 title = forms.CharField(max_length=50,min_length=2) #校验最大长度50,最小长度2 14 desc = forms.CharField(max_length=60,required=False) 15 method = forms.IntegerField() #0 1 2 3 16 url = forms.URLField() 17 params = forms.CharField(max_length=100) 18 19 #form钩子函数 20 #校验字段是否在枚举数中 21 def clean_method(self):#clean_ +字段名----校验单个字段,必须是clean开头 22 method = self.cleaned_data.get('method') 23 if method not in (0,1,2,3): 24 raise ValidationError('method值不对') 25 return method 26 27 #校验重复性 28 def clean_title(self): 29 title = self.cleaned_data.get('title') 30 if models.Case.objects.filter(title=title).count() > 0: 31 raise ValidationError('用例标题已存在') 32 return title 33 34 #检验多个字段 35 def clean(self): 36 title = self.cleaned_data.get('title') 37 desc = self.cleaned_data.get('desc') 38 39 class CaseView(View): 40 #form校验 41 def post(self, request): 42 #form校验 43 form = CaseForm(request.POST) 44 if form.is_valid(): 45 # 返回{'title':xxx,'desc':xxx},**组装成{title=xxx,desc=xxx} 46 models.Case.objects.create(**form.cleaned_data)#将数据存入数据库 47 data = {'code': 0,'msg': '添加成功'} 48 else: 49 print(form.errors.as_json)#打印错误信息 50 data = {'code': -1,'msg': '参数错误'} 51 return JsonResponse(data)
2.使用modelform校验入参:上面1中很多参数都是与数据库中的数据紧密相关,而且写了很多类似与models中的代码,可以进一步使用modelform来简化
1 from django.core.exceptions import ValidationError 2 from django.http import JsonResponse 3 from django.views import View 4 from django import forms 5 from . import models 6 7 class CaseForm2(forms.ModelForm):#CaseForm2关联Case表的所有字段 8 class Meta: 9 fields = '__all__' #__all__代表所有字段都是必传字段 10 exclude = ['case_set','run_count'] #排除哪些字段 11 model = models.Case #关联Case表 12 13 class CaseView(View): 14 # modelform校验 15 def post(self, request): 16 #modelform校验 17 form = CaseForm2(request.POST) 18 if form.is_valid(): 19 # 返回{'title':xxx,'desc':xxx} 20 # cleaned_data读取表单返回的值,返回类型为字典dict型 21 # models.Case.objects.create(**form.cleaned_data) 22 form.save() # form提供save方法,将表单的返回值即form.cleaned_data保存起来 23 data = {'code':0,'msg':'添加成功'} 24 else: 25 print(form.errors.as_json)#打印错误信息 26 data = {'code':-1,'msg':'参数错误'} 27 return JsonResponse(data)
优化:
将modelform代码从views.py中抽出来,在testcase应用目录下创建forms.py存放form
forms.py
1 from django import forms 2 from django.core.exceptions import ValidationError 3 from utils.tools import FormatFormError #引入格式化错误信息 4 5 from . import models 6 class CaseSetForm(forms.ModelForm,FormatFormError): 7 class Meta: 8 model = models.CaseSet 9 exclude = ['is_delete'] 10 11 12 class CaseForm(forms.ModelForm): 13 class Meta: 14 model = models.Case 15 exclude = ['is_delete','case_set','run_count','run_time'] 16 17 #modelform也可以定义钩子方法 18 def clean_method(self): 19 pass 20 21 class CaseFormOld(forms.Form):#校验参数满足条件,不满足条件时报错 22 '''校验请求参数''' 23 title = forms.CharField(max_length=50,min_length=2) 24 desc = forms.CharField(max_length=60,required=False) 25 method = forms.IntegerField() #0 1 2 3 26 url = forms.URLField() 27 params = forms.CharField(max_length=100) 28 29 #form钩子函数 30 #校验字段是否在枚举数中 31 def clean_method(self):#clean_ +字段名----校验单个字段 32 method = self.cleaned_data.get('method') 33 if method not in (0,1,2,3): 34 raise ValidationError('method值不对') 35 return method 36 37 #校验重复性 38 def clean_title(self): 39 title = self.cleaned_data.get('title') 40 if models.Case.objects.filter(title=title).count() > 0: 41 raise ValidationError('用例标题已存在') 42 return title 43 44 #检验多个字段 45 def clean(self): 46 title = self.cleaned_data.get('title') 47 desc = self.cleaned_data.get('desc')
views.py
1 from django.db.models import Q 2 from django.forms import model_to_dict 3 from django.http import JsonResponse 4 from django.core.paginator import Paginator 5 from . import models 6 from . import forms 7 from django.views import View 8 9 class CaseView(View): 10 def get(self,request): 11 # 分页 12 limit = request.GET.get('limit',20) 13 page = request.GET.get('page',1) 14 search = request.GET.get('search')#模糊搜索关键字 15 filter_field = ['id','title','method']#关键字精确查询,通过哪些字段查询 16 filter_dict = {} 17 for field in filter_field: 18 value = request.GET.get(field) 19 if value: 20 filter_dict[field] = value 21 if filter_dict: 22 case_sets = models.Case.objects.filter(**filter_dict) 23 elif search:#模糊查询 24 case_sets = models.Case.objects.filter(Q(title__contains=search) | 25 Q(desc__contains=search) | 26 Q(url__contains=search) | 27 Q(params__contains=search))#模糊查询 28 else: 29 case_sets = models.Case.objects.filter(is_delete=False)#查询所有 30 paginator = Paginator(case_sets,limit) 31 page_data = paginator.page(page) 32 33 data = [] 34 for c in page_data: 35 d = model_to_dict(c) 36 data.append(d) 37 response = {'code': 0, 'msg': '添加成功', 'data': data,'count':paginator.count} 38 return JsonResponse(response, json_dumps_params={'ensure_ascii': False}) # 汉字不转义 39 40 41 #form校验 42 # def post(self, request): 43 # #form校验 44 # form = CaseForm(request.POST) 45 # if form.is_valid(): 46 # # 返回{'title':xxx,'desc':xxx} 47 # models.Case.objects.create(**form.cleaned_data) 48 # data = {'code':0,'msg':'添加成功'} 49 # else: 50 # print(form.errors.as_json)#打印错误信息 51 # data = {'code':-1,'msg':'参数错误'} 52 # return JsonResponse(data) 53 54 # form校验 55 def post(self, request): 56 #modelform校验 57 form = forms.CaseForm(request.POST) 58 if form.is_valid(): 59 # 返回{'title':xxx,'desc':xxx} 60 models.Case.objects.create(**form.cleaned_data) 61 data = {'code':0,'msg':'添加成功'} 62 else: 63 print(form.errors.as_json)#打印错误信息 64 data = {'code':-1,'msg':'参数错误'} 65 return JsonResponse(data) 66 67 68 69 def delete(self,request): 70 id = request.GET.get('id') 71 models.Case.objects.filter(id=id).update(is_delete=True) 72 response = {'code': 0, 'msg': '成功'} 73 return JsonResponse(response, json_dumps_params={'ensure_ascii': False}) # 汉字不转义 74 75 def put(self,request): 76 pass 77 78 class CaseSet(View): 79 def get(self): 80 case_sets = models.CaseSet.objects.filter(is_delete=False) 81 data = [] 82 for c in case_sets: 83 d = model_to_dict(c) 84 data.append(d) 85 response = {'code': 0, 'msg': '添加成功', 'data': data} 86 return JsonResponse(response, json_dumps_params={'ensure_ascii': False}) # 汉字不转义 87 88 def post(self, request): 89 form = forms.CaseSetForm(request.POST) 90 if form.is_valid():#form返回为真 91 # models.CaseSet.objects.create(**form.cleaned_data) 92 form.save() #form提供save方法,字段存入数据库中,同上一行create操作 93 data = {'code': 0, 'msg': '添加成功'} 94 else: 95 print(form.errors.as_json) 96 data = {'code': -1, 'msg': form.error_msg} 97 return JsonResponse(data) # 通过JsonResponse类返回json字符串
urls.py
1 from django.urls import path 2 from . import views 3 4 urlpatterns = [ 5 path('case',views.CaseView.as_view()) #cvb 6 7 ]