68 drf 响应类reponse 序列化数据校验与写入

1.内部类

就是当前类的配置类

1.序列化组件的配置类

2.数据库model配置类

解释: 伪代码         继承的model类支持db_name,所以Meta类要使用db_name的写法

"""
class Car(Model):
    name = CharFields()
    class Meta:
        db_name = "表名"

# Car表,将会name作为Car表的字段
(内部可以通过Car.name访问到name)
(内部可以通过Car.Meta.db_name访问到 "表名" => table的表名)
    if Car.Meta.db_name:
        table的表名 = Car.Meta.db_name
    else:
        table的表名 = Car.__class__.name
"""

2.响应类分析  reponse

1.reponse类源码分析

响应类Response源码

def __init__(self, data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None):
    pass

data:响应的数据 - 空、字符串、数字、列表、字段、布尔
status:网络状态码
template_name:drf说自己也可以支持前后台不分离返回页面,但是不能和data共存(不会涉及)
headers:响应头(不用刻意去管)
exception:是否是异常响应(如果是异常响应,可以赋值True,没什么用)
content_type:响应的结果类型(如果是响应data,默认就是application/json,所有不用管)

2.运用

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status    #网络状态码模块 可以进去看源码

from . import models, serializers

class UserAPIView(APIView):
    def get(self, request, *args, **kwargs):
        pk = kwargs.get(‘pk‘)
        if pk:  # 单查
            # 1)数据库交互拿到资源obj或资源objs
            # 2)数据序列化成可以返回给前台的json数据
            # 3)将json数据返回给前台
            try:
                obj = models.User.objects.get(pk=pk)
                serializer = serializers.UserModelSerializer(obj, many=False)
                return Response({
                    ‘status‘: 0,
                    ‘msg‘: ‘ok‘,
                    ‘result‘: serializer.data
                })
            except:
                return Response(
                    data={
                        ‘status‘: 1,
                        ‘msg‘: ‘pk error‘
                    },
                    status=status.HTTP_400_BAD_REQUEST,  # 比直接写400更具有描述性
                    exception=True
                )

3.序列化参数分析

1.源码分析

序列化类BaseSerializer
def __init__(self, instance=None, data=empty, **kwargs):
    pass

instance:是要被赋值对象的 - 对象类型数据赋值给instance
data:是要被赋值数据的 - 请求来的数据赋值给data
kwargs:内部有三个属性:many、partial、context
    many:操作的对象或数据,是单个的还是多个的
    partial:
    context:   下面两个参数后期会讲

2.运用    序列化实现单查  群查

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from . import models, serializers

class UserAPIView(APIView):
    def get(self, request, *args, **kwargs):
        pk = kwargs.get(‘pk‘)
        if pk:  # 单查
            # 1)数据库交互拿到资源obj或资源objs
            # 2)数据序列化成可以返回给前台的json数据
            # 3)将json数据返回给前台
            try:
                obj = models.User.objects.get(pk=pk)
                serializer = serializers.UserModelSerializer(obj, many=False)      instance
                return Response({
                    ‘status‘: 0,
                    ‘msg‘: ‘ok‘,
                    ‘result‘: serializer.data
                })
            except:
                return Response(
                    data={
                        ‘status‘: 1,
                        ‘msg‘: ‘pk error‘
                    },
                    status=status.HTTP_400_BAD_REQUEST,  # 比直接写400更具有描述性
                    exception=True
                )

        else:  # 群查
            # 1)数据库交互拿到资源obj或资源objs
            # 2)数据序列化成可以返回给前台的json数据
            # 3)将json数据返回给前台
            queryset = models.User.objects.all()
            serializer = serializers.UserModelSerializer(queryset, many=True)
            return Response({
                    ‘status‘: 0,
                    ‘msg‘: ‘ok‘,
                    ‘results‘: serializer.data
                })

    def post(self, request, *args, **kwargs):
        # 单增
        # 1)从请求request中获得前台提交的数据
        # 2)将数据转换成Model对象,并完成数据库入库操作(序列化组件完成)
        # 3)将入库成功的对象列化成可以返回给前台的json数据(请求与响应数据不对等:请求需要提交密码,响应一定不展示密码)
        # 4)将json数据返回给前台

        # 1)将前台请求的数据交给序列化类处理
        # 2)序列化类执行校验方法,对前台提交的所有数据进行数据校验:校验失败就是异常返回,成功才能继续
        # 3)序列化组件完成数据入库操作,得到入库对象
        # 4)响应结果给前台
        serializer = serializers.UserModelSerializer(data=request.data)
        if serializer.is_valid():
            # 校验成功 => 入库 => 正常响应
            obj = serializer.save()
            return Response({
                ‘status‘: 0,
                ‘msg‘: ‘ok‘,
                ‘result‘: ‘新增的那个对象‘
            }, status=status.HTTP_201_CREATED)
        else:
            # 校验失败 => 异常响应
            return Response({
                ‘status‘: 1,
                ‘msg‘: serializer.errors,
            }, status=status.HTTP_400_BAD_REQUEST)

4.反序列化实现单增

1.数据校验: serializer.is_valid():

2.数据保存:obj = serializer.save()

3.错误信息:serializer.errors

    def post(self, request, *args, **kwargs):
        # 单增
        # 1)从请求request中获得前台提交的数据
        # 2)将数据转换成Model对象,并完成数据库入库操作(序列化组件完成)
        # 3)将入库成功的对象列化成可以返回给前台的json数据(请求与响应数据不对等:请求需要提交密码,响应一定不展示密码)
        # 4)将json数据返回给前台

        # 1)将前台请求的数据交给序列化类处理
        # 2)序列化类执行校验方法,对前台提交的所有数据进行数据校验:校验失败就是异常返回,成功才能继续
        # 3)序列化组件完成数据入库操作,得到入库对象
        # 4)响应结果给前台
        serializer = serializers.UserModelSerializer(data=request.data)
        if serializer.is_valid():
            # 校验成功 => 入库 => 正常响应
            obj = serializer.save()
            return Response({
                ‘status‘: 0,
                ‘msg‘: ‘ok‘,
                ‘result‘: ‘新增的那个对象‘
            }, status=status.HTTP_201_CREATED)
        else:
            # 校验失败 => 异常响应
            return Response({
                ‘status‘: 1,
                ‘msg‘: serializer.errors,
            }, status=status.HTTP_400_BAD_REQUEST)

5.基础校验规则

后面练习多体会

from rest_framework import serializers
from rest_framework import exceptions

from . import models
class UserModelSerializer(serializers.ModelSerializer):
    # 自定义反序列化字段(所有校验规则自己定义,也可以覆盖model已有的字段)
    # 覆盖model有的字段,不明确write_only会参与序列化过程
    password = serializers.CharField(min_length=4, max_length=8, write_only=True)
    # 自定义字段,不明确write_only序列化会报错,序列化会从model中强行反射自定义字段,但是model没有对于字段
    re_password = serializers.CharField(min_length=4, max_length=8, write_only=True)

    class Meta:
        # 该序列化类是辅助于那个Model类的
        model = models.User
        # 设置参与序列化与反序列化字段
        # 插拔式:可以选择性返回给前台字段(插头都是在Model类中制造)
        # fields = [‘name‘, ‘age‘, ‘height‘, ‘sex‘, ‘icon]

        # 第一波分析:
        # 1)name和age,在fields中标明了,且没有默认值,也不能为空,入库时必须提供,所有校验时必须提供
        # 2)height,在fields中标明了,但是有默认值,所有前台不提供,也能在入库时采用默认值(可以为空的字段同理)
        # 3)password,没有在fields中标明了,所以校验规则无法检测password情况,但是即使数据校验提供了,
        #       也不能完成入库,原因是password是入库的必填字段
        # 4)gender和img是自定义插拔@property字段,默认就不会进行校验(不参与校验)
        # fields = [‘name‘, ‘age‘, ‘height‘, ‘gender‘, ‘img‘]

        # 第二波分析:
        # 1)如何区分 序列化反序列化字段 | 只序列化字段(后台到前台) | 只反序列化字段(前台到后台)
        #       不做write_only和read_only任何限制 => 序列化反序列化字段
        #       只做read_only限制 => 只序列化字段(后台到前台)
        #       只做write_only限制 => 只反序列化字段(前台到后台)

        # 2)对前台到后台的数据,制定基础的校验规则(了解)
        #       CharField(max_length, min_length, errors_kwargs)
        #       DecimalField(min_value, max_value, max_digits, decimal_places,error_messages)

        # 3)如果一个字段有默认值或是可以为空,比如height,如何做限制
        #       虽然有默认值或是可以为空,能不能强制限制必须提供,可以通过required是True来限制
        #       前台提交了该字段,我就校验,没提交我就不校验:1)required是False 2)有校验规则
        fields = [‘name‘, ‘age‘, ‘password‘, ‘height‘, ‘gender‘, ‘img‘, ‘re_password‘]

        # 第三波分析
        # 1)制定的简易校验规则(没有制定)后,可以再通过字段的 局部钩子 对该字段进行复杂校验
        # 2)每个字段进行逐一复杂校验后,还可以进行集体的 全局钩子 校验
        #       涉及对自定义反序列化字段的校验:re_password(要参与校验,但是不会入库)

        # 校验规则
        extra_kwargs = {
            ‘name‘: {
                # ‘write_only‘: True,
                # ‘read_only‘: True
            },
            ‘password‘: {
                ‘write_only‘: True,
                ‘min_length‘: 3,
                ‘max_length‘: 8,
                ‘error_messages‘: {  # 可以被国际化配置替代
                    ‘min_length‘: ‘太短‘,
                    ‘max_length‘: ‘太长‘
                }
            },
            ‘height‘: {
                # ‘required‘: True,
                ‘min_value‘: 0,
            }
        }

6.自定义校验规则    全局钩子 局部钩子

from rest_framework import serializers
from rest_framework import exceptions

from . import models
class UserModelSerializer(serializers.ModelSerializer):
    # 自定义反序列化字段(所有校验规则自己定义,也可以覆盖model已有的字段)
    # 覆盖model有的字段,不明确write_only会参与序列化过程
    password = serializers.CharField(min_length=4, max_length=8, write_only=True)
    # 自定义字段,不明确write_only序列化会报错,序列化会从model中强行反射自定义字段,但是model没有对于字段
    re_password = serializers.CharField(min_length=4, max_length=8, write_only=True)
    fields = [‘name‘, ‘age‘, ‘password‘, ‘height‘, ‘gender‘, ‘img‘, ‘re_password‘]
    # 注:局部全局钩子,是和Meta同缩减,属于序列化类的
    # 局部钩子:validate_要校验的字段(self, 要校验的字段值)
    # 全局钩子:validate(self, 所以字段值的字典)
    # 校验规则:成功返回传来的数据 | 失败抛出异常

    def validate_name(self, value):
        if ‘g‘ in value.lower():
            raise exceptions.ValidationError("这个g不行")
        else:
            return value

    def validate(self, attrs):
        print(attrs)
        password = attrs.get(‘password‘)  # 只是拿出来校验
        re_password = attrs.pop(‘re_password‘)  # 必须取出校验,因为不能入库

        if password != re_password:
            raise exceptions.ValidationError({‘re_password‘: ‘两次密码不一致‘})
        else:
            return attrs

数据写入

    
from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import status

from . import models, serializers
     def post(self, request, *args, **kwargs):
        # 单增
        # 1)从请求request中获得前台提交的数据
        # 2)将数据转换成Model对象,并完成数据库入库操作(序列化组件完成)
        # 3)将入库成功的对象列化成可以返回给前台的json数据(请求与响应数据不对等:请求需要提交密码,响应一定不展示密码)
        # 4)将json数据返回给前台

        # 1)将前台请求的数据交给序列化类处理
        # 2)序列化类执行校验方法,对前台提交的所有数据进行数据校验:校验失败就是异常返回,成功才能继续
        # 3)序列化组件完成数据入库操作,得到入库对象
        # 4)响应结果给前台
        serializer = serializers.UserModelSerializer(data=request.data)
        if serializer.is_valid():
            # 校验成功 => 入库 => 正常响应
            obj = serializer.save()
            return Response({
                ‘status‘: 0,
                ‘msg‘: ‘ok‘,
                ‘result‘: ‘新增的那个对象‘
            }, status=status.HTTP_201_CREATED)
        else:
            # 校验失败 => 异常响应
            return Response({
                ‘status‘: 1,
                ‘msg‘: serializer.errors,
            }, status=status.HTTP_400_BAD_REQUEST)

原文地址:https://www.cnblogs.com/bigbox/p/12609813.html

时间: 2024-08-29 09:14:10

68 drf 响应类reponse 序列化数据校验与写入的相关文章

内部类,drf响应类,序列化与反序列化

内部类 # 概念:将类定义在一个类的内部,被定义的类就是内部类 # 特点:内部类及内部类的所以名称空间,可以直接被外部类访问的 # 应用:通过内部类的名称空间,给外部类额外拓展一些特殊的属性(配置),典型的Meta内部类 - 配置类 class Book(model.Model): class Meta: db_model = "owen_book" # 配置自定义表名 class BookSerializer(serializers.ModelSerializer): class M

序列化-请求数据校验。。。。。。

序列化 拿到所有的角色数据 1.urls.py 2.models.py  假设只有3个角色 3.views.py from api import models import json json只能序列化python的基本数据类型!!!! QueryDict是django定义的类!!!! 所以以下这种操作会报错!!! 4.解决方案:取某个字段,然后转成list数据,再转成json数据. 返回数据:注意汉字都变成字节码了!!! 5.显示中文  ensure_ascii=False json序列化方法

DRF ---- 视图类 数据工具类 工具视图集 视图集

目录 一. 视图类 1. ApiView 2. GenericAPIView get_queryset 配置queryset get_object 配置 lookup_url_kwarg get_serializer 配置 serializer_class GenericAPIView配置 结合使用: 二.视图工具类 1)ListModelMixin 群查 2)CreateModelMixin 单增 3) RetrieveModelMixin 单查 4)UpdateModelMixin 单改 5

数据校验工具类

思路, 1.传入要校验的属性以及如果校验不过提示信息 2.如果数据校验不过返回json 格式信息. 3.不满足条件抛出自定义异常,然后在异常处理器中获取信息,return 信息 一.自定义异常 public class LyonException extends RuntimeException{ private static final long serialVersionUID = 1L; private String msg; private int code = 500; code 默认

DRF解析组件以及序列化组件

一.知识点回顾: 1.三元运算: 三元运算能够简化我们的代码,请看如下代码: # 定义两个变量 a = 1 b = 2 # 判断a的真假值,如果为True,则将判断表达式的前面的值赋给c,否则将判断表达式后面的值赋给c c = a if a else b print(c) # 1 # 因为a的真假值判断为True,所以c为1 # 定义两个变量 a = 0 b = 2 # 判断a的真假值,如果为True,则将判断表达式的前面的值赋给c,否则将判断表达式后面的值赋给c c = a if a else

DRF框架之 serializers 序列化组件

1. 什么是序列化,其实在python中我们就学了序列化工具json工具,就是吧信息存为类字典形式 2. DRF框架自带序列化的工具: serializers 3. DRF框架 serializers 分为:第一种 Serializer   第二种 ModelSerializer 第一种用法之 Serializer from django.db import models # Create your models here. class Book(models.Model): nid = mod

Struts2学习笔记(九)——数据校验

Struts2的数据校验属于服务器端校验,Struts2 支持校验方式 : 手动校验(代码校验) :在服务器端通过编写java代码,完成数据校验 自动校验(配置校验) :XML配置校验(主流) 和 注解配置校验 1.手动校验 1)Struts2的手动校验步骤: 首先要从页面中获取对应的标签name属性的值,在动作类action中声明同名的属性,提供get和set方法; 要继承ActionSupport类或者实现Validateable接口: 重写Validateable接口的validate()

基于QTcpSocket和QTcpServer的Tcp通讯以及QDataStream序列化数据

最近要在QT下开发Tcp通讯,发送序列化数据以便于接收. 这里涉及到几个问题: 1.QTcpSocket.QTcpServer的通讯 2.QDataStream序列化数据 多的不说,直接上干货!!! 客户端: tcpclient.h 1 #ifndef TCPCLIENT_H 2 #define TCPCLIENT_H 3 4 #include <QMainWindow> 5 #include <qt4/Qt/qtcpsocket.h> 6 #include <Qt/qhos

wpf企业应用之数据校验

wpf中使用IDataErrorInfo实现数据校验,绑定实体需要实现了此接口,并在UI绑定表达式中添加ValidatesOnDataErrors=True,这样数据校验发生时,wpf会调用该接口中的索引然后返回相应的校验信息,我们为控件添加属性触发器来响应校验. 下面结合我的项目中的一部分代码做一说明,具体效果见 wpf企业级开发中的几种常见业务场景. UI绑定 <TextBox Text="{Binding EditProduct.Num, ValidatesOnExceptions=