django form --day15

一、cvb,fvb

CVB class view 

 1 from django.views import View
 2 class Articl_View(View):
 3 
 4     def get(self,request):
 5         print('get请求。。。')
 6         categories = Category.objects.all()  # 返回所有的分类
 7         return render(request, 'form.html', locals())  #
 8 
 9     def post(self,request):
10         print('post请求。。。')
11         title = request.POST.get('title')
12         desc = request.POST.get('desc')
13         category = request.POST.get('category')
14         content = request.POST.get('content')
15         article = Article(title=title, desc=desc, category_id=category)
16         article.save()
17         # return render(request,'index.html')
18         return HttpResponseRedirect('/index')  # 重定向

 

FVB 函数view

 

 1 def add_article(request):
 2     if request.method == 'GET':#第一次请求接口,是get请求
 3         categories =Category.objects.all()#返回所有的分类
 4         return render(request,'form.html',locals())#
 5     else:
 6         title = request.POST.get('title')
 7         desc = request.POST.get('desc')
 8         category = request.POST.get('category')
 9         content = request.POST.get('content')
10         article = Article(title=title,desc=desc,category_id=category)
11         article.save()
12         # return render(request,'index.html')
13         return HttpResponseRedirect('/index')#重定向

 

form表单方式和js中的axoius的区别

  1、form表单提交后页面会刷新

  2、js不会刷新页面

CSRF token验证失败,请求被中断问题:

  1、CSRF为了防止重复提交

  2、每次请求

客户端访问了get请求,服务端返回页面,但是页面会带一个字符串,然后添加功能后请求post 但是客户端没有带入字符串的请求,就会报错403

django默认post请求都需要加入CSRF token

解决办法:

1、settings.py文件中将以下注释内容注释,但是没有解决重复提交的问题

1 MIDDLEWARE = [
2     'django.middleware.security.SecurityMiddleware',
3     'django.contrib.sessions.middleware.SessionMiddleware',
4     'django.middleware.common.CommonMiddleware',
5     # 'django.middleware.csrf.CsrfViewMiddleware',
6     'django.contrib.auth.middleware.AuthenticationMiddleware',
7     'django.contrib.messages.middleware.MessageMiddleware',
8     'django.middleware.clickjacking.XFrameOptionsMiddleware',
9 ]

 

2、form.html中 如果用form表单需要增加  {% csrf_token %} 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>添加文章入口</title>
 6 </head>
 7 <body>
 8 <form action="/add_article/" method="post">
 9     {% csrf_token %}
10     title:<input name="title" type="text">
11     desc:<input name="desc" >
12     content:<input name="content">
13 <select name = "category">
14     {% for a in categories %}
15     <option value = "{{ a.id }}">{{ a.name }}</option>
16     {% endfor %}
17 </select>
18 <input type="submit" value="提交">
19 </form>
20 </body></html>

 

问题:参数需要校验

导入库

1 from django import forms
2 from django.core.exceptions import ValidationError

方式一、使用Form校验 views.py文件中实现

 1 class CaseForm(forms.Form):
 2     '''校验请求参数'''
 3     title = forms.CharField(max_length=50,min_length=2)
 4     desc = forms.CharField(max_length=60,required=False)
 5     method = forms.IntegerField() # 0 1 2 3
 6     url = forms.URLField()
 7     params = forms.CharField(max_length=100)
 8 
 9     def clean_method(self): #钩子函数,校验method参数
10         method = self.cleaned_data.get('method')
11         if method not in (0,1,2,3):
12             raise ValidationError('method值不对')
13         return  method
14 
15     def clean_title(self):#校验单个字段
16         title = self.cleaned_data.get('title')
17         if models.Case.objects.filter(title=title).count()>0:
18             raise ValidationError('用例标题已经存在')
19         return title
20 
21     def clean(self):#校验多个字段
22         title = self.cleaned_data.get('title')
23         method = self.cleaned_data.get('method')

方式二、和数据录相关继承(forms.ModelForm)views.py文件中实现

1 class CaseSetForm(forms.ModelForm):#集合校验数据
2     class Meta:
3         model = models.CaseSet
4         fields = '__all__'#全部校验
5         exclude = ['is_delete']#排除不校验参数

方式三、单独新创建forms.py的文件,只写form校验内容

 1 from django import forms
 2 from django.core.exceptions import ValidationError
 3 
 4 from . import models
 5 
 6 
 7 class CaseSetForm(forms.ModelForm):#集合校验数据
 8     class Meta:
 9         model = models.CaseSet
10         fields = '__all__'#全部校验
11         exclude = ['is_delete']#排除不校验参数

views.py中实现

 1 from . import models
 2 from . import forms
 3 from django.views import View
 4 
 5 class CaseView(View):
 6     def post(self,request):
 7         form = forms.CaseForm(request.POST)#这里具体引用
 8         if form.is_valid():
 9             models.Case.objects.create(**form.cleaned_data)
10             data = {'code': 0, 'msg': '添加成功'}
11         else:
12             data = {'code':-1,'msg':form.error_msg}#显示具体的错误信息
13         return JsonResponse(data)

 

二、前后端分离实现方式实例

整体思路如图:

 

 

 

 

1、新创建应用

1.1新创建的应用--testcase

pycharm编辑器--Tools--Run manage.py Task...

输入:startapp +应用名称

 

1.2 dj_test 目录下settings.py增加应该名称

 

2、testcase目录下创建数据库models.py

 1 from django.db import models
 2 
 3 # Create your models here.
 4 # 公共的字段,然后子类继承父类中的公共方法,问题:创建的表的时候会创建,所以增加【Class Meta】
 5 class BaseModel(models.Model):
 6     create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
 7     update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
 8     is_delete = models.BooleanField(verbose_name='是否删除', default=False)
 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 
16 
17     def __str__(self):
18         return self.name
19 
20     class Meta:
21         db_table = 'case_set'
22         verbose_name ='用例集合表'
23         verbose_name_plural = verbose_name
24 
25 
26 class Case(BaseModel):
27     title = models.CharField(verbose_name='用例标题',max_length=80,db_index=True,unique=True)
28     desc = models.CharField(verbose_name='用例描述',max_length=120)
29     method_choice = [
30         [0,'get'],
31         [1,'post'],
32         [2,'put'],
33         [3,'delete'],
34     ]
35     method = models.SmallIntegerField(choices=method_choice,verbose_name='请求方式',default=0)
36     url = models.URLField(max_length=50,verbose_name='请求url')
37     params = models.TextField(verbose_name='请求参数')
38     run_count = models.IntegerField(verbose_name='运行次数',default=0,null=True,blank=True)
39     run_time = models.DateTimeField(verbose_name='运行时间',null=True,blank=True)
40     case_set = models.ManyToManyField(CaseSet,db_constraint=False,verbose_name='用例集合',null=True,blank=True)#用例和用例集合之间建立连接,多对多
41 
42 
43     def __str__(self):
44         return self.title
45 
46     class Meta:
47         db_table = 'case'
48         verbose_name ='用例表'
49         verbose_name_plural = verbose_name

 

2.1 生成数据库

pycharm编辑器--Tools--Run manage.py Task... 

 

2.2 同步数据库 

migrate

 

 

 

 3、testcase目录下views.py编辑接口实现

3.1 普通实现方式--不建议

添加集合:

 1 def case_set(request):
 2     # 添加用例集合
 3     name = request.POST.get('name')
 4     desc = request.POST.get('desc')
 5     if name.strip() and desc.strip():
 6         models.CaseSet.objects.create(name=name, desc=desc)
 7         data = {'code': 0, 'msg': '添加成功'}
 8     else:
 9         data = {'code': -1, 'msg': '参数错误'}
10     return JsonResponse(data)

查看集合:

 1 def case_set_all(req):
 2     #查看用例
 3     case_sets = models.CaseSet.objects.filter(is_delete=False)
 4 
 5     data = []#定义
 6     for c in case_sets:
 7         d = model_to_dict(c)#实现把数据转成字典
 8         data.append(d)#将字典添加到list中
 9     response = {'code': 0, 'msg': '成功', 'data': data}
10 
11     return JsonResponse(response, json_dumps_params={'ensure_ascii': False})  # {'code': 0, 'msg': '成功',data:[ ]},json_dumps_paramsjson_dumps_params显示中文

3.2resultful方式

def case_set_new(req):#restful的风格,开发接口的规范
    if req.method == 'GET':
        case_sets = models.CaseSet.objects.filter(is_delete=False)
        data = []
        for c in case_sets:
            d = model_to_dict(c)
            data.append(d)
        response = {'code': 0, 'msg': '成功', 'data': data}
        return JsonResponse(response, json_dumps_params={'ensure_ascii': False})  # {'code': 0, 'msg': '成功',data:[ ]}
    elif req.method == 'POST':
        name = req.POST.get('name')
        desc = req.POST.get('desc')
        if name.strip() and desc.strip():
            models.CaseSet.objects.create(name=name, desc=desc)
            data = {'code': 0, 'msg': '添加成功'}
        else:
            data = {'code': -1, 'msg': '参数错误'}
        return JsonResponse(data)
    elif req.method == 'PUT':
        pass
    elif req.method=='DELETE':
        pass

3.3 class方式

 1 class CaseSet(View):
 2 
 3     def post(self,request):
 4         form = CaseSetForm(request.POST)
 5         if form.is_valid():
 6             form.save() #
 7             # models.CaseSet.objects.create(**form.cleaned_data)
 8             data = {'code': 0, 'msg': '添加成功'}
 9         else:
10             print(form.errors.as_data())
11             data = {'code': -1, 'msg': '参数错误'}
12         return JsonResponse(data)
13 
14     def get(self,request):
15         case_sets = models.CaseSet.objects.filter(is_delete=False)
16         data = []
17         for c in case_sets:
18             d = model_to_dict(c)
19             data.append(d)
20         response = {'code': 0, 'msg': '成功', 'data': data}
21         return JsonResponse(response, json_dumps_params={'ensure_ascii': False})

3.4用例接口实现

 1 class CaseView(View):
 2     def post(self,request):
 3         # form = CaseForm(request.POST)
 4         form = CaseForm2(request.POST)
 5         if form.is_valid():
 6             print('这个是用了form校验的')
 7             models.Case.objects.create(**form.cleaned_data)
 8             data = {'code': 0, 'msg': '添加成功'}
 9         else:
10             print(form.errors.as_data())
11             data = {'code':-1,'msg':'参数错误'}
12         return JsonResponse(data)
13 
14     def get(self,request):
15         case_sets = models.Case.objects.filter(is_delete=False)
16         data = []
17         for c in case_sets:
18             d = model_to_dict(c)
19             data.append(d)
20         response = {'code': 0, 'msg': '成功', 'data': data}
21         return JsonResponse(response, json_dumps_params={'ensure_ascii': False})
22 
23     def delete(self,request):
24         id = request.GET.get('id')
25         models.Case.objects.filter(id=id).update(is_delete=True)
26         response = {'code': 0, 'msg': '成功'}
27         return JsonResponse(response, json_dumps_params={'ensure_ascii': False})
28 
29     def put(self,request):
30         pass

  

4、testcase目录下新增个urls.py

 1 from django.urls import path
 2 from . import views,views_new
 3 
 4 urlpatterns = [
 5     path('add_case_set',views.case_set),
 6     path('case_set',views.case_set_all),
 7 
 8     path('case_set_new',views_new.CaseSet.as_view()),
 9     path('case',views_new.CaseView.as_view()),
10 
11 ]

 

5、dj_test目录下urls.py配置testcase的urls

 6、分页功能的实现views.py

 1     def get(self,request):
 2         limit = request.GET.get('limit',20)
 3         page = request.GET.get('page',1)
 4         case_sets = models.Case.objects.filter(is_delete=False)
 5         paginator = Paginator(case_sets,limit)
 6         page_data = paginator.page(page)
 7         data = []
 8         for c in page_data:
 9             d = model_to_dict()
10             data.append(d)
11         response = {'code':0,'msg':'','data':data,'count':paginator.count}
12         return JsonResponse(response,json_dumps_params={'ensure_ascii': False})

7、模糊搜索

 1 def get(self,request):
 2         limit = request.GET.get('limit',20)
 3         page = request.GET.get('page',1)
 4         search = request.GET.get('search')
 5         if search:
 6             case_sets= models.Case.objects.filter(Q(title__contains=search)|
 7                                                   Q(desc__contains=search)|
 8                                                   Q(url__contains=search)|
 9                                                   Q(params__contains=search))
10         else:  
11             case_sets = models.Case.objects.filter(is_delete=False)
12         paginator = Paginator(case_sets,limit)
13         page_data = paginator.page(page)
14         data = []
15         for c in page_data:
16             d = model_to_dict()
17             data.append(d)
18         response = {'code':0,'msg':'','data':data,'count':paginator.count}
19         return JsonResponse(response,json_dumps_params={'ensure_ascii': False})

8、实现按参数过滤

 

 1 from django.db.models import Q 
 2    def get(self,request):
 3         limit = request.GET.get('limit',20)
 4         page = request.GET.get('page',1)
 5         search = request.GET.get('search')
 6         filter_field = ['id','title','method']#支持通过哪些字段来过滤
 7         filter_dict = {}
 8         for field in filter_field:
 9             value = request.GET.get(field)#从请求中获取参数
10             if value:
11                 filter_dict[field] = value
12         if filter_dict:
13             case_sets = models.Case.objects.filter(**filter_dict)  # 精确查询,优先级高
14         elif search:
15             case_sets= models.Case.objects.filter(Q(title__contains=search)|
16                                                 Q(desc__contains=search)|
17                                                 Q(url__contains=search)|
18                                                 Q(params__contains=search))
19         else:
20             case_sets = models.Case.objects.filter(is_delete=False)
21         paginator = Paginator(case_sets,limit)
22         page_data = paginator.page(page)
23         data = []
24         for c in page_data:
25             d = model_to_dict()
26             data.append(d)
27         response = {'code':0,'msg':'','data':data,'count':paginator.count}
28         return JsonResponse(response,json_dumps_params={'ensure_ascii': False})

 三、整理代码优化

 1     def get_paginator(self,data_list):#实现分页
 2         limit = self.request.GET.get('limit',20)#一页要显示多少数据
 3         page = self.request.GET.get('page',1)#第几页的数据,默认是第一页
 4         paginator = Paginator(data_list, limit)
 5         page_data = paginator.page(page)#分页
 6         return page_data,paginator
 7 
 8     def get_search_data(self):
 9         data = []
10         search = self.request.GET.get('search')
11         if search:
12             data = models.Case.objects.filter(Q(title__contains=search) |
13                                        Q(desc__contains=search) |
14                                        Q(url__contains=search) |
15                                        Q(params__contains=search)
16                                        )
17         return data
18 
19 
20     def get_filter_data(self):
21         data = []
22         filter_field = ['id','title','method']#支持通过哪些字段来过滤
23         filter_dict = {} #{'id':1,'title':abc}
24         for field in filter_field: #
25             value = self.request.GET.get(field)
26             if value:
27                 filter_dict[field] = value
28         if filter_dict:
29             data = models.Case.objects.filter(**filter_dict)
30         return data
 1     def get(self,request):     
 2         if self.get_filter_data():
 3             case_sets = self.get_filter_data()
 4         elif self.get_search_data():
 5             case_sets = self.get_search_data()
 6         else:
 7             case_sets = models.Case.objects.filter(is_delete=False) #查询所有的
 8         page_data,paginator = self.get_paginator(case_sets)
 9         data = []
10         for c in page_data:
11             d = model_to_dict(c)
12             data.append(d)
13         response = {'code': 0, 'msg': '成功', 'data': data,'count':paginator.count}
14         return JsonResponse(response, json_dumps_params={'ensure_ascii': False})

 

posted @ 2020-07-02 23:37  洛歆陌离  阅读(97)  评论(0编辑  收藏  举报