Django serializer优化类视图的实现示例


Posted in Python onJuly 16, 2020

一. create优化

在serializer序列化中,我们通过创建序列化器对象的方式地简化了视图函数的代码,前端传入的数据通过反序列化操作进行了各种数据校验,代码如下:

from django.http import JsonResponse
from django.views import View
import json
from .models import Project
from .serializers import ProjectsSerializer


class ProjectsPage(View):
  '''
  类视图
  '''
  def post(self, request):

    input_data = json.loads(request.body)

    serializer_obj = ProjectsSerializer(data=input_data)

    if not serializer_obj.is_valid():
      return JsonResponse({"code": 1, "res": "error", "msg": serializer_obj.errors})

    obj = Project.objects.create(**input_data)

    ser_obj = ProjectsSerializer(instance=obj)

    return JsonResponse(ser_obj.data, status=201)

可以看到,这里创建了两个序列化器类对象,一个serializer_obj用于反序列化参数校验(用data接受前端参数),一个ser_obj用于序列化输出(用instance接受模型类对象),其实可以去掉ser_obj,然后调用serializer_obj的save()方法,save()方法会自动调用序列化器类对象中定义的create方法

def post(self, request):
    """
    post请求,新增数据
    :param request:
    :return:
    """
    try:

      data = json.loads(request.body, encoding='utf-8')
    except Exception as e:
      result = {
        "msg": "参数有误",
        "code": 0
      }
      return JsonResponse(result, status=400)

    ser_obj = ProjectsSerializer(data=data)
    try:
      ser_obj.is_valid(raise_exception=True)
    except Exception as e:
      result = {"msg": "参数有误"}
      result.update(ser_obj.errors)
      return JsonResponse(result, status=400)

    ser_obj.save()

    resp = {"msg": "创建成功"}
    resp.update(ser_obj.data)

    return JsonResponse(resp, status=201)

序列化器类中的create方法需要提前定义,该方法是父类的create方法,我们可以进行重写,父类方法源码如下:

def create(self, validated_data):
    return [
      self.child.create(attrs) for attrs in validated_data
    ]

重写父类的create方法,并返回模型类对象

def create(self, validated_data):

    obj = Project.objects.create(**validated_data)

    return obj

使用postman验证结果:

Django serializer优化类视图的实现示例

写入数据库的数据:

Django serializer优化类视图的实现示例

二. update优化

def put(self, request, pk):
    try:
      obj = Project.objects.get(id=pk)
    except Exception as e:
      result = {
        "msg": "参数有误",
        "code": 0
      }
      return JsonResponse(result, status=400)

    update_data = json.loads(request.body)

    serializer_obj = ProjectsSerializer(data=update_data)
    if not serializer_obj.is_valid():
      return JsonResponse({"code": 1, "res": "error", "msg": serializer_obj.errors})

    obj.name = serializer_obj.validated_data.get('name') or obj.name
    obj.leader = serializer_obj.validated_data.get('leader') or obj.leader
    obj.desc = serializer_obj.validated_data.get('desc') or obj.programmer
    obj.tester = serializer_obj.validated_data.get('tester') or obj.tester
    obj.save()

    ser_obj = ProjectsSerializer(instance=obj)

    return JsonResponse(ser_obj.data, status=201)

上面创建了两个序列化器类的对象,可以进行合并,合并方式跟create方法有点差别,这里是给序列化器对象同时传入data和instance,然后调用save()方法,它会自动去调用序列化器类中的update方法
优化后的put方法

def put(self, request, pk):
    try:
      obj = Project.objects.get(id=pk)
    except Exception as e:
      result = {
        "msg": "参数有误",
        "code": 0
      }
      return JsonResponse(result, status=400)

    request_data = request.body

    try:
      python_data = json.loads(request_data)
    except Exception as e:
      result = {
        "msg": "参数有误",
        "code": 0
      }
      return JsonResponse(result, status=400)

    serializer_obj = ProjectsSerializer(instance=obj, data=python_data)
    try:
      serializer_obj.is_valid(raise_exception=True)
    except Exception as e:
      resp = {'msg': '参数有误'}
      resp.update(serializer_obj.errors)
      return JsonResponse(resp, status=400)

    serializer_obj.save()
    resp = {'msg': '修改成功'}
    resp.update(serializer_obj.data)

    return JsonResponse(resp, status=201)

序列化器类中的update方法需要提前定义,该方法是父类的update方法,我们可以进行重写,父类方法源码如下:

def update(self, instance, validated_data):
    raise_errors_on_nested_writes('update', self, validated_data)
    info = model_meta.get_field_info(instance)
    m2m_fields = []
    for attr, value in validated_data.items():
      if attr in info.relations and info.relations[attr].to_many:
        m2m_fields.append((attr, value))
      else:
        setattr(instance, attr, value)
    instance.save()
    for attr, value in m2m_fields:
      field = getattr(instance, attr)
      field.set(value)

    return instance

在序列化器类中重写父类的updata方法,并返回模型类对象

def update(self, instance, validated_data):
    """
    更新数据
    :param instance: 待更新的模型类对象
    :param validated_data: 校验通过之后的数据
    :return: 模型类对象
    """
    instance.name = validated_data.get('name') or instance.name
    instance.leader = validated_data.get('leader') or instance.leader
    instance.tester = validated_data.get('tester') or instance.tester
    instance.desc = validated_data.get('desc') or instance.desc
    instance.save()
    return instance

使用post满验证结果:

Django serializer优化类视图的实现示例

Django serializer优化类视图的实现示例

友情提示:在调用序列化器类对象的save()方法时,可以以关键字的方式传参,它会自动添加到create方法的validated_data中,应用场景:判断当前项目是哪个用户创建的

到此这篇关于Django serializer优化类视图的实现示例的文章就介绍到这了,更多相关Django serializer优化类视图内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python的Bottle框架中返回静态文件和JSON对象的方法
Apr 30 Python
Windows下搭建python开发环境详细步骤
Jul 20 Python
Python基于回溯法子集树模板解决选排问题示例
Sep 07 Python
Python中turtle作图示例
Nov 15 Python
详解Python map函数及Python map()函数的用法
Nov 16 Python
Python中常用信号signal类型实例
Jan 25 Python
用Python下载一个网页保存为本地的HTML文件实例
May 21 Python
python3+pyqt5+itchat微信定时发送消息的方法
Feb 20 Python
Pycharm简单使用教程(入门小结)
Jul 04 Python
python 实现多维数组(array)排序
Feb 28 Python
django model通过字典更新数据实例
Apr 01 Python
如何用Python 加密文件
Sep 10 Python
python中plt.imshow与cv2.imshow显示颜色问题
Jul 16 #Python
Python实现GIF图倒放
Jul 16 #Python
浅谈python处理json和redis hash的坑
Jul 16 #Python
Python requests及aiohttp速度对比代码实例
Jul 16 #Python
Python3 搭建Qt5 环境的方法示例
Jul 16 #Python
python3实现将json对象存入Redis以及数据的导入导出
Jul 16 #Python
Python必须了解的35个关键词
Jul 16 #Python
You might like
漂亮但不安全的CTB
2006/10/09 PHP
php 引用(&)详解
2009/11/20 PHP
PHP print类函数使用总结
2010/06/25 PHP
PHP程序级守护进程的实现与优化的使用概述
2013/05/02 PHP
ThinkPHP CURD方法之data方法详解
2014/06/18 PHP
Thinkphp多文件上传实现方法
2014/10/31 PHP
php获取文件后缀的9种方法
2016/03/22 PHP
PHP hebrev()函数用法讲解
2019/02/21 PHP
php+layui数据表格实现数据分页渲染代码
2019/10/26 PHP
javascript 带有滚动条的表格,标题固定,带排序功能.
2009/11/13 Javascript
JavaScript控制table某列不显示的方法
2015/03/16 Javascript
一道常被人轻视的web前端常见面试题(JS)
2016/02/15 Javascript
AngularJS 面试题集锦
2016/09/06 Javascript
表单input项使用label同时引用Bootstrap库导致input点击效果区增大问题
2016/10/11 Javascript
关于vue.js组件数据流的问题
2017/07/26 Javascript
原生JavaScript实现todolist功能
2018/03/02 Javascript
微信小程序实现的一键连接wifi功能示例
2019/04/24 Javascript
在Layui 的表格模板中,实现layer父页面和子页面传值交互的方法
2019/09/10 Javascript
json解析大全 双引号、键值对不在一起的情况
2019/12/06 Javascript
详解JavaScript作用域、作用域链和闭包的用法
2020/09/03 Javascript
Python数据类型之Number数字操作实例详解
2019/05/08 Python
详解python和matlab的优势与区别
2019/06/28 Python
浅谈python多进程共享变量Value的使用tips
2019/07/16 Python
Python.append()与Python.expand()用法详解
2019/12/18 Python
Python实现投影法分割图像示例(二)
2020/01/17 Python
利用纯CSS3实现动态的自行车特效源码
2017/01/20 HTML / CSS
幼儿教育感言
2014/02/05 职场文书
公司建议书怎么写
2014/05/15 职场文书
小学学习雷锋活动总结
2014/07/03 职场文书
机电专业毕业生自我鉴定2014
2014/10/04 职场文书
党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
解约证明模板
2015/06/19 职场文书
2015元旦感言
2015/12/09 职场文书
Django cookie和session的应用场景及如何使用
2021/04/29 Python
Centos环境下Postgresql 安装配置及环境变量配置技巧
2021/05/18 PostgreSQL
MYSQL数据库使用UTF-8中文编码乱码的解决办法
2021/05/26 MySQL