接收前端参数(反序列化) 且进行校验(含自定义校验) + 接口前段数据插入数据库

参考:

https://www.bilibili.com/video/BV1XR4y157rk?p=6&vd_source=caabcbd2a759a67e2a3de8acbaaf08ea

针对模型字段和属性见 https://blog.csdn.net/weixin_45827423/article/details/113405360

 

查询数据库的信息赋值实体类---序列化       见: https://www.cnblogs.com/kaibindirver/p/13264461.html

接收前端参数到实体类---反序列化

1、自定义校验失败提示的信息

2、用模型自己的1属性进行校验

      #3、数据验证 ,抛出异常,代码不会往下执行
        serializer.is_valid(raise_exception=True)

(可以把校验的那块BookSerializers独立出去)

from rest_framework import serializers


# 针对模型设计序列化器--(即前端要传什么字段给我们)
class BookSerializers(serializers.Serializer):
    id=serializers.IntegerField(read_only=True) #在客户端提交数据【反序列化阶段不会要求有id字段】
    name=serializers.CharField(required=True) #required=True=反序列化阶段必填
    sex=serializers.BooleanField(default=True) #default=True,反序列化客户端没有填,默认为True
    # 注意error_messages属性为触发错误提示的错误信息
    age=serializers.IntegerField(max_value=100,min_value=0,error_messages=
    {"max_value":"错误信息提示","min_value":"错误信息提示"}) #在反序列化必须 0<age<=100
    # "max_value": "错误信息提示", "min_value": "错误信息提示"
    description=serializers.CharField(allow_null=True,allow_blank=True) #允许客户端不填内容,或者传递一个""



import json
# Create your views here.
class BookView(APIView):

    # 反序列化--采用字段选项来验证数据
    def get(self, request):
        #1、接收客户端提交的数据
        # data=json.dumps(request.body)
        # 模拟客户端请求body
        data={
            "name" :"amin",
            "sex": 1,
            "age":30,
            "description":"这家伙很懒"
        }
        #2、实例化序列化器,获取序列化对象
        serializer = BookSerializers(data=data)
        #3、调用序列化器进行数据验证  不抛出异常,返回True or False
        ret=serializer.is_valid()
        print(f"{ret}")
        # 获取验证后的结果
        if ret:
            print(serializer.validated_data)
        else:
            print(serializer.errors)
            # 输出例子:{'age': [ErrorDetail(string='Ensure this value is greater than or equal to 0.', code='min_value')]}
            #字段形式告诉你那个字段错误了
            #指定错误字段的信息
            print(serializer.errors["age"])
        # 操作数据库
        # 响应前端
        return JsonResponse({})
反序列化的一些参数:
required 表明反序列化时,必须输入,默认是True

default 反序列化时使用的默认值

allow_null 反序列化,是否允许是None,默认是False

error_messages:错误信息展示

反序列化的一些检验参数:
 max_length 最大长度
 min_length 最小长度
 allow_blank 是否允许为空
 trim_whitespace 是否截断空白字符
 max_value 最大值
 min_value 最小值

read_only和write_only:

1、read_only: 序列化时需要该字段,反序列化时可以不需要该字段的数据

2、write_only: 是反序列化时需要该字段,序列化时不会有该字段的数据

序列化和反序列:
          序列化就是从数据库中读取数据,返回给前端(查询数据时)。

          反序列化就是将数据写入到数据库中,前端将数据传递给后端。(更新数据和增加数据) 

简化判断错误校验你,只需要把 serializer.is_valid(raise_exception=True) 加上raise_exception=True,当校验错误即返回了错误信息给前端-----!!!!!工作中最常用!!!!!

# 反序列化--采用字段选项来验证数据抛出异常,工作中最常用
    def get(self, request):
        #1、接收客户端提交的数据
        # data=json.dumps(request.body)
        # 模拟客户端请求body
        data={
            "name" :"amin",
            "sex": 1,
            "age":130,
            "description":"这家伙很懒"
        }
        #2、实例化序列化器,获取序列化对象
        serializer = BookSerializers(data=data)
        #3、调用序列化器进行数据验证 ,抛出异常,代码不会往下执行
        serializer.is_valid(raise_exception=True)
        # 校验正常,响应前端 {"name": "amin", "sex": 1, "age": 130, "description": "这家伙很懒"}
        return JsonResponse(serializer.validated_data)

 

 

 

------------------------------------------------------------------自定义校验---------------------------------

把校验的1独立出来了,视图层还是调用BookView函数

1、单字段校验

2、多字段校验

3、指定某字段的校验函数

from rest_framework import serializers


# --------------------------#外部验证函数(注意这个方法在类外面)-------------------
# 在下面模型设计序列化器
# --对应字段使用属性validators指定这个函数做校验--注意要在模型设计序列化器前面
def check_classmate(data):
    '''外部验证函数'''
    if len(data) !=3:
        raise serializers.ValidationError(detail="自定义校验不符合3", code="code不知做啥的")
        # 验证成功以后,必须返回数据,否则该字段数据返回None
    return data

# 针对模型设计序列化器
class BookSerializers(serializers.Serializer):
    id=serializers.IntegerField(read_only=True) #在客户端提交数据【反序列化阶段不会要求有id字段】 可以不传
    # validators指定外部校验函数,值是一个列表,列表里是是函数名,不能是字符串
    name=serializers.CharField(required=True,validators=[check_classmate]) #required=True=反序列化阶段必填
    sex=serializers.BooleanField(default=True) #default=True,反序列化客户端没有填,默认为True
    # 注意error_messages属性为触发错误提示的错误信息
    age=serializers.IntegerField(max_value=100,min_value=0,error_messages=
    {"max_value":"错误信息提示","min_value":"错误信息提示"}) #在反序列化必须 0<age<=100
    # "max_value": "错误信息提示", "min_value": "错误信息提示"
    description=serializers.CharField(allow_null=True,allow_blank=True) #允许客户端不填内容,或者传递一个""

    # -------------------validate--验证单个字段(单字段校验)------------------
    #自定义验证字段,方法名的格式必须以 validate_<字段名>为名称,否则序列化器不识别!
    def validate_name(self,data):
        '''验证单个字段
        validate开头的方法,会自动被is_valid调用 即是视图层使用的 serializer.is_valid()
        '''
        # 校验name字段
        if data in ["python","django"]:
            # 判断字段不符合抛出异常 {"name":["自定义校验不符合"]}
            raise serializers.ValidationError(detail="自定义校验不符合",code="code不知做啥的")
        # 验证成功以后,必须返回数据,否则该字段数据返回None
        return data
    #-------------------validate--验证所有客户端传过来的字段(多字段校验)-------------

    # 校验代码的对象方法
    def validate(self,attrs):
        '''
        验证来自客户端的所有数据
        类似校验会员注册的密码和确认密码,就只能在validate方法中校验
        validate是固定方法名
        参数 attrs 是序列化器实例化的打他选项数据
        '''
        print(f"attrs={attrs}")
        #307班只能有女生,且age<18
        if attrs["sex"] ==1 and attrs["age"]:
            raise serializers.ValidationError(detail="自定义校验不符合2", code="code不知做啥的")
        return attrs

 

 

模型设计序列化校验 默认的是英文错误,修改项目的settings文件

LANGUAGE_CODE ='zh-hans'

返回的校验信息就会变成中文

 

 

 

 

 

-----------------插入数据库(拿到插入的id)-------

view.py

BookSerializers接受前端数据模型(上面的)

Publisher 是数据库数据模型modle层

from django.shortcuts import render
from rest_framework.views import APIView
from django.http import HttpResponse,JsonResponse
from OneApp.models import Publisher
from OneApp.serializers import BookSerializers

import json
# Create your views here.
class BookView(APIView):

    # 反序列化--采用字段选项来验证数据抛出异常,工作中最常用
    def get(self, request):
        #1、接收客户端提交的数据
        # data=json.dumps(request.body)
        # 模拟客户端请求body
        data={
            "name" :"18",
            # "sex": 1,
            # "age":100,
            # "description":""
        }
        #2、实例化序列化器,获取序列化对象
        serializer = BookSerializers(data=data)
        #3、调用序列化器进行数据验证 ,抛出异常,代码不会往下执行
        serializer.is_valid(raise_exception=True)
        #拿到校验成功的请求参数
        data=serializer.validated_data  # OrderedDict([('name', '18')])
        print(json.dumps(data))   #序列化输出  {"name": "18"}
        print(serializer.data)    #序列化输出  {"name": "18"}
        # 操作数据库插入
        aa=Publisher.objects.create(**data)
        BookSerializers(instance=aa).data  #获取插入的信息 {'id': 26, 'name': '18'}   ------这步可以拿到新增后的id
        # 校验正常,响应前端
        return JsonResponse(serializer.validated_data)

 

 

 

更便捷的写法

serializers.py

from rest_framework import serializers
from OneApp.models import Publisher

# 针对模型设计序列化器
class BookSerializers(serializers.Serializer):
    id=serializers.IntegerField(read_only=True) #在客户端提交数据【反序列化阶段不会要求有id字段】 可以不传
    # validators指定外部校验函数,值是一个列表,列表里是是函数名,不能是字符串

    name=serializers.CharField(required=True) #required=True=反序列化阶段必填
    # sex=serializers.BooleanField(default=True) #default=True,反序列化客户端没有填,默认为True
    # 注意error_messages属性为触发错误提示的错误信息
    # phone=serializers.IntegerField(read_only=True)
    # description=serializers.CharField(allow_null=True,allow_blank=True) #允许客户端不填内容,或者传递一个""


# 模型操作方法
#     新增
    def create(self,validated_data):
        '''添加数据
        添加数据操作,方法名固定为create,固定参数validated_data就是验证成功的结果,就自动实现从字段变为模型对象的过程
        '''
        publisher=Publisher.objects.create(**validated_data)
        return publisher

#     更新
    def update(self,instance,validated_data):
        '''
        更新数据
        方法名固定为update
        固定参数instance,实例化序列化器对象时,必须传入的模型对象
        固定参数validated_data就是验证成功以后的结果
        更新数据以后,就自动实现了从字段变成模型对象的过程
        '''
        instance.name=validated_data["name"]
        instance.save()
        return instance

 

view.py

from django.shortcuts import render
from rest_framework.views import APIView
from django.http import HttpResponse,JsonResponse
from OneApp.models import Publisher
from OneApp.serializers import BookSerializers
from django.core import serializers
import json
# Create your views here.
class BookView(APIView):

    # 新增动作
    def get2(self, request):
        #1、接收客户端提交的数据
        data={
            "name" :"18",
            # "sex": 1,
            # "age":100,
            # "description":""
        }
        #2、实例化序列化器,获取序列化对象
        serializer = BookSerializers(data=data)
        #3、调用序列化器进行数据验证 ,抛出异常,代码不会往下执行
        serializer.is_valid(raise_exception=True)
        # 4、获取验证以后的结果,操作数据库
        serializer.save()
        # 校验正常,响应前端
        return JsonResponse(serializer.data,status=201)  #{"id": 39, "name": "18"}


    #更新动作
    def get(self, request):
        # 根据客户端传的数据主键id
        try:
            authorId=Publisher.objects.get(pk=2)
        except Student.DoesNotExist:
            return JsonResponse({"errors":"不存在数据"},status=400)
        #1、接收客户端提交的数据
        data={
            "name" :"zhangsan5",
            # "sex": 1,
            # "age":100,
            # "description":""
        }
        #2、修改操作中的实例化序列化对象
        serializer = BookSerializers(instance=authorId,data=data)
        #3、数据验证 ,抛出异常,代码不会往下执行
        serializer.is_valid(raise_exception=True)
        # 4、获取验证以后的结果,操作数据库
        serializer.save()        #可以传递一些模型中不存在,获不需要校验的数据 ----
        # 校验正常,响应前端
        return JsonResponse(serializer.data,status=201)  #{"id": 39, "name": "18"}

 

 

 

不是很懂

 

查询序列化见 https://www.cnblogs.com/kaibindirver/p/17147733.html

posted @ 2022-10-09 00:20  凯宾斯基  阅读(346)  评论(0编辑  收藏  举报