Django学习笔记(14)form和modelform

在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 ]

猜你喜欢

转载自www.cnblogs.com/bugoobird/p/13371092.html