django前后端分离 form_03(验证,数据查询,代码优化)

1.优化代码

把form验证的返回报错写成一个共用的类 该类在工程下建立了一个uitls-tools.py

class FormatErrMsg:

    @property #装饰器-属性方法 调用的时候不需要加()
    def error_msg(self):
        #self.get_json_data() 是form自带的友好的报错提示 返回的是一个字典
        message = ‘‘
        for error_params, v in self.errors.get_json_data().items():
            error_message = v[0].get(‘message‘)
            m = ‘%s:%s‘ % (error_params, error_message)
            message += m
        return message

2.单独在工程下面建立一个forms.py文件,用来专门存放form验证,这样就保证views里只写逻辑,而不涉及验证

#创建这个文件专门写forms 验证数据
from django import forms

from uitls.tools import FormatErrMsg
from . import models

#用关联数据库的约束验证form
class CaseSetFormALL(forms.ModelForm,FormatErrMsg):
    class Meta:
        fields = ‘__all__‘#关联了所有字段
        model = models.CaseSet#关联数据库CaseSet
        exclude = [‘is_delete‘,‘create_time‘,‘update_time‘]#排查不校验的字段

class CaseFormALL(forms.ModelForm,FormatErrMsg):
    class Meta:
        fields = ‘__all__‘
        model = models.Case
        exclude = [‘case_set‘,‘create_time‘,‘update_time‘]

#自定义
class CaseForm(forms.Form,FormatErrMsg):
    ‘‘‘校验请求参数‘‘‘
    title = forms.CharField(max_length=50,min_length=2)
    desc = forms.CharField(max_length=70,required=False)#required=False 默认desc可以为空
    method = forms.IntegerField()
    url = forms.URLField()
    params = forms.CharField(max_length=100)

    #自定义校验
    #单个参数校验@1
    # def clean_method(self):
    #     method = self.cleaned_data.get(‘method‘)#先校验上述那些基本的格式,然后在校验自定义的规则
    #     if method not in (0,1,2,3):
    #         raise ValidationError(‘method值不对‘)
    #     return method
    # 单个参数校验@2
    # def clean_title(self):
    #     title = self.cleaned_data.get(‘title‘)
    #     if models.Case.objects.filter(title=title).count()>0:
    #         raise ValidationError(‘标题重复‘)
    #     return title
    # def clean(self):#多个参数组合校验‘method‘,‘title‘
    #     method = self.cleaned_data.get(‘method‘)
    #     title = self.cleaned_data.get(‘title‘)
    #     if method not in (0,1,2,3):
    #         raise forms.ValidationError(‘method参数错误‘)#抛出异常
    #     elif models.Case.objects.filter(title=title).count()>0:
    #         raise forms.ValidationError(‘标题重复‘)#抛出异常
    #     return self.cleaned_data

class CaseSetForm(forms.Form,FormatErrMsg):
    name = forms.CharField(max_length=50,min_length=2)
    desc = forms.CharField(max_length=50,required=False)

    def clean_name(self):
        name = self.cleaned_data.get(‘name‘)
        if models.CaseSet.objects.filter(name=name).count()>0:
            raise forms.ValidationError(‘用例集合名称重复‘)
        return name

3.在views.py中写 增删改查的逻辑

from django.forms import model_to_dict,ValidationError
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from django import forms
from . import forms
from django.core.paginator import Paginator
from . import models
from django.db.models import Q
from uitls.tools import Page
# Create your views here.

#常规写法@1,@2,用例集合表
#用例集合添加 post请求 需要传两个参数 即集合表的增加操作@1
def case_set(request):
    name = request.POST.get(‘name‘)
    desc = request.POST.get(‘desc‘)
    if name.strip() and desc.strip() and models.CaseSet.objects.filter(name=name).count()<1:
        models.CaseSet.objects.create(name=name,desc=desc)
        data = {‘code‘:0,‘msg‘:‘添加成功‘}
    else:
        data = {‘code‘:-1,‘msg‘:‘添加失败‘}
    return JsonResponse(data)

#查询集合 get请求 不需要传参 获取集合表的数据 查询操作@2
def case_set_all(request):
    case_sets = models.CaseSet.objects.filter(is_delete=False)#查询所有集合
    data = []
    #把查询出来的转换成字典通过model_to_dict方法,并添加进data列表中,最终返回[{‘xx‘:xx},{‘xx‘:xx}]
    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})

#一个函数写两个URL请求的逻辑上述两种方式的结合
def case_set_new(request):
    name = request.POST.get(‘name‘)
    desc = request.POST.get(‘desc‘)
    if request.method==‘GET‘:
        case_sets = models.CaseSet.objects.filter(is_delete=False)  # 查询所有集合
        data = []
        # 把查询出来的转换成字典通过model_to_dict方法,并添加进data列表中,最终返回[{‘xx‘:xx},{‘xx‘:xx}]
        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})
    elif request.method==‘POST‘:
        if name.strip() and desc.strip() and models.CaseSet.objects.filter(name=name).count()<1:
            models.CaseSet.objects.create(name=name, desc=desc)
            data = {‘code‘: 0, ‘msg‘: ‘添加成功‘}
        else:
            data = {‘code‘: -1, ‘msg‘: ‘添加失败‘}
        return JsonResponse(data)

#cvb方式,用例集合表,根据请求不同,执行相应的操作
class CaseSet(View):
    #增加数据
    def post(self,request):
        # form = forms.CaseSetFormALL(request.POST)
        form = forms.CaseSetForm(request.POST)
        if form.is_valid():
            models.CaseSet.objects.create(**form.cleaned_data)
            data = {‘code‘: 0, ‘msg‘: ‘添加成功‘}
        else:
            data = {‘code‘: -1, ‘msg‘: form.error_msg}
        return JsonResponse(data)

    def get_paginator(self,data_list):#分页函数
        limit = self.request.GET.get(‘limit‘, 3)  # 默认不传 每页显示3条
        page_num = self.request.GET.get(‘page_num‘, 1)  # 默认不传 显示第一页
        paginator = Paginator(data_list,limit)
        page_data = paginator.page(page_num)
        return page_data,paginator

    def get_search_data(self):#模糊查询
        data = []
        search = self.request.GET.get(‘search‘)
        if search:
            data = models.CaseSet.objects.filter(Q(name__contains=search)|Q(desc__contains=search))
        return data

    def get_filter_data(self):#精确查询
        data = []
        # 定义精确查询的字段为一个列表
        filter_field = [‘name‘, ‘desc‘, ‘id‘]
        filter_dict = {}
        for field in filter_field:
            value = self.request.GET.get(field)
            if value:
                filter_dict[field] = value
        if filter_dict:  # 精确查询
            data = models.CaseSet.objects.filter(**filter_dict)
        return data

    #查找数据
    def get(self,request):
        if self.get_filter_data():#调用精确查询函数
            case_sets = self.get_filter_data()
        elif self.get_search_data():#调用模糊查询函数
            case_sets = self.get_search_data()
        else:
        # 查询所有
            case_sets = models.CaseSet.objects.filter(is_delete=False)
        page_data,paginator = self.get_paginator(case_sets)#调用分页函数
        data = []
        # 把查询出来的转换成字典通过model_to_dict方法,并添加进data列表中,最终返回[{‘xx‘:xx},{‘xx‘:xx}]
        for c in page_data:
            d = model_to_dict(c)
            data.append(d)
        response = {‘code‘: 0, ‘msg‘: ‘成功‘, ‘data‘: data,‘count‘:paginator.count}#count是总数据
        return JsonResponse(response, json_dumps_params={‘ensure_ascii‘: False})

#cvb方式,用例表
class Case(View):
    #增加数据
    def post(self,request):
        form = forms.CaseForm(request.POST) #通过post方法拿到请求的数据
        # form = forms.CaseFormALL(request.POST)#通过post方法拿到请求的数据
        #开始验证 form.is_valid() 返回一个bool类型的数据 通过返回True 不通过返回False
        if form.is_valid():
            #如果校验通过会返回一个字典{‘title‘:xxx,‘desc‘:xxx,‘method‘:xx,‘url‘:xx,‘params‘:xx}
            # print(form.cleaned_data)
            models.Case.objects.create(**form.cleaned_data)#字典前面加**转换为title=xxx,desc=xxxx
            data = {‘code‘: 0, ‘msg‘: ‘成功‘}
        else:
            data = {‘code‘: -1, ‘msg‘: form.error_msg}
            return JsonResponse(data)
    #查找数据
    def get(self,request):
        case_sets = models.Case.objects.filter(is_delete=False)  # 查询所有集合
        data = []
        # 把查询出来的转换成字典通过model_to_dict方法,并添加进data列表中,最终返回[{‘xx‘:xx},{‘xx‘:xx}]
        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})
    #删除数据
    def delete(self,request):
        id = request.GET.get(‘id‘)
        models.Case.objects.filter(id=id).update(is_delete=True)
        response = {‘code‘: 0, ‘msg‘: ‘成功‘}
        return JsonResponse(response, json_dumps_params={‘ensure_ascii‘: False})

原文地址:https://www.cnblogs.com/mhmh007/p/12170762.html

时间: 2024-10-08 23:40:03

django前后端分离 form_03(验证,数据查询,代码优化)的相关文章

django的crsf机制防御详解及在前后端分离中post数据到django-vue

django的crsf机制防御详解及在前后端分离中post数据到django 更新于: 2018-07-28 |  分类于 django CSRF(Cross Site Request Forgery) 跨站点伪造请求 某个用户已经登陆了你的网站,另外有一个恶意的网站有一个指向你网站的链接,那么当用户点击这个链接时,就会请求你的网站,但是你的网站以为是用户发来的请求,这时恶意网站就得逞了. django的应对措施 用户在post请求时,发送给用户一个token,然后在django内部实现了一个校

django 前后端分离,后端接口实现

博客篇我们使用的是前后端不分离的方式进行实现,前后端不分离实现方式,主要用于小型的项目,且一个人就可以搞定所有,但是中大型的应用还是用的前后端分离的方式进行的 前后端分离方式后台主要给前端提供接口,前端JS调用后台的接口,根据接口定义的传参进行传参,得到返回值,然后展现在页面上,或者对数据进行了操作,把操作后的数据传给后端,后端进行数据的更新等 下面的例子我们主要从基本的增删改查进行设计后台接口部分 一.准备工作 1.modles.py文件中,创建student表,用于进行增删改查 class

从零开始搭建django前后端分离项目 系列一(技术选型)

前言 最近公司要求基于公司的hadoop平台做一个关于电信移动网络的数据分析平台,整个项目需求大体分为四大功能模块:数据挖掘分析.报表数据查询.GIS地理化展示.任务监控管理.由于页面功能较复杂,所以采用前后端分离方式开发.前端采用webpack+vue+vue-router+axios技术栈,后端用django进行开发.从搭建到上线,整个项目前前后后花了差不多一个月时间,中途也遇到一些问题,不过还好都解决了.由于是个人项目,所以我打算把源码贡献出来大家一起讨论学习. 源代码 https://g

Django前后端分离跨域请求问题

一.问题背景 之前使用django+vue进行前后端分离碰到跨域请求问题,跨域(域名或者端口不同)请求问题的本质是由于浏览器的同源策略导致的,当请求的响应不是处于同一个域名和端口下,浏览器不会接受响应,同源策略也是浏览器针对请求的安全问题所作出的一种保护行为.针对跨域问题,可以有下面的解决方式: JSONP方式 自定义中间件,设置响应头 使用django-cors-headers包 二.解决方式 (一)自定义中间件 JSONP本质上是利用html的一些不受同源策略影响的标签属性src,例如:<a

Nginx+uwsgi+celery+supervisor部署Django前后端分离项目

本实验实现了负载均衡.反向代理.动静分离,还实现了根据客户端设备user-agent进行转发,也就是移动端和PC端访问的页面不一样. 1. 项目部署逻辑图 2. 环境准备 服务器:6台VM操作系统:CentOS7LB.www.wap:安装Nginxuwsgi1.uwsgi2:安装nfs-utils.Python3解释器.virtualenvNFS:安装NFSMRCS:安装MySQL.Redis.virtualenv 注意:这里不介绍软件的安装Nginx安装参考:http://blog.51cto

前后端分离之——接口数据返回---标准格式

开发中,如果前端和后端,在没有统一返回数据格式,我们来看一下会发生什么: 后台开发人员A,在接口返回时,习惯返回一个返回码code=0000,然后返回数据: 后台开发人员B,在接口返回时,习惯直接返回一个boolean类型的success=true,然后返回数据: 后台开发人员C,在接口返回时,习惯在接口失败时返回码为code=0000. 可以看到,上面的三个开发人员,都没有大问题,没有谁对谁错,只要给前端接口文档,前端都是可以接上接口的.但是,在项目功能越来越多,接口数量持续增长时,对开发人员

Django 前后端分离 token和cookie、session对比

HTTP协议本身是无状态的,所以需要一个标志来对用户身份进行验证 1.cookie 用户登录成功后,会在服务器存一个session,同时发送给客户端一个cookie,这个cookie里面有唯一标识该用户的sessionID 数据需要客户端和服务器同时存储 用户再进行请求操作时,需要带上cookie,在服务器进行验证 cookie是有状态的 2.token 用户进行任何操作时,都需要带上一个token token的存在形式有很多种,header/requestbody/url 都可以 这个toke

从零开始搭建django前后端分离项目 系列五(实战之excel流式导出)

项目中有一处功能需求是:需要在历史数据查询页面进行查询字段的选择,然后由后台数据库动态生成对应的excel表格并下载到本地. 如果文件较小,解决办法是先将要传送的内容全生成在内存中,然后再一次性传入Response对象中: 如果文件较大时,我们可以考虑向HttpResponse传递一个迭代器,流式的向客户端传递数据. view.py视图 @csrf_exempt def exportData(request): format = request.GET.get('format') pk = re

django前后端分离部署

部署静态文件: 静态文件有两种方式1:通过django路由访问2:通过nginx直接访问 方式1: 需要在根目录的URL文件中增加,作为入口 url(r'^$', TemplateView.as_view(template_name="index.html")), 在setting中更改静态资源位置 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path