首页 > 其他分享 >3.校验,格式化,ModelSerializer使用

3.校验,格式化,ModelSerializer使用

时间:2024-08-01 10:40:47浏览次数:5  
标签:格式化 name author self 校验 ModelSerializer publish serializers data

【一】反序列化校验

1)三层校验

  • 字段自己校验
    • 直接写在字段类的属性上
  • 局部钩子
    • 在序列化中写validata_字段名
  • 全局钩子
# serializers.py
class BookSerializer(serializers.Serializer):
    # 1) name字段的要大于1小于10
    name = serializers.CharField(min_length=1, max_length=10)
    publish = serializers.CharField()

    # 重建
    def create(self, validated_data):
        book = Book.objects.create(**validated_data)
        return book
    # 2) 局部钩子(针对name字段)
    def validate_name(self, name):
        if "sb" in name:
            raise ValueError('书名中不能有sb')
        else:
            return name
    # 3) 全局钩子
    def validate(self, attrs):
        name = attrs.get('name')
        publish= attrs.get('publish')
        if name == str(publish):
            raise ValidationError('不能相同')
        else:
            return attrs

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from App.models import Book
from App.serializers import BookSerializer


class BookViewSet(APIView):
    # 查询全部
    def get(self, request):
        books = Book.objects.all()
        serializer = BookSerializer(instance=books, many=True)
        return Response(serializer.data)

    # 添加图书
    def post(self, request):
        serializer = BookSerializer(data=request.data)
        ### 若出错,停止代码,直接抛出异常
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response('ok', status=200)

【二】定制返回格式:source

1)定制表中某个字段

  • 直接改名称,并在字段类的属性上添加source='数据库的字段名'
# serializers.py
name = serializers.CharField()
# name改成book_name
book_name = serializers.CharField(source='name')

2)定制模型表

# 将指定字段输出的数据加是'_NB'

# models.py的指定库中
@property
def new_name(self):
    return self.name + '_NB'
# serializers.py
name = serializers.CharField(source='new_name')

3)跨表查询

# 从Book表到publish表
publish= serializers.CharField(source='publish.name')

【三】定制返回格式:序列化

1)一对多关系

1.方式一:使用source

publish= serializers.CharField(source='publish.name')

2.方式二:在模型表中写

# 序列化类中(serializers.py)
# 字典格式用DecimalField,列表用ListField
publish_detail = serializers.DecimalField()

# 指定的模型表内(models.py)
def publish_detail(self):
    return {'name': self.publish.name, 'addr': self.publish.addr}

3.方式三:在序列化类中写

publish = serializers.SerializerMethodField()
    def get_publish(self, obj):
        return {'name': obj.publish.name, 'addr': obj.publish.addr}

4.方式四:使用子序列化

# 在serializers.py内新写函数
class PublishSerializer(serializers.Serializer):
    name = serializers.CharField()
    addr = serializers.CharField()
# 序列化类中写入
publish = PublishSerializer()

2)多对多关系

  • 与一对多相同
# 方式三示例
author = serializers.SerializerMethodField()

def get_author(self, obj):
    authors = obj.author_book.all()
    list_data = []
    for author in authors:
        list_data.append({'name': author.name, 'gender': author.get_gender_display()})
	return list_data

【四】反序列化

  • 通过在序列化类字段内添加参数实现判断
    • read_only=True :只进行序列化操作
    • write_only=True:只进行反序列化操作

1)添加 - 示例

class BookViewSet(APIView):
	def post(self, request):
        serializer = BookSerializer(data=request.data)
        # 若出错,停止代码,直接抛出异常
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({'code': 200,'message': '添加成功','data': serializer.data})
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from App.models import Book, Author

class BookSerializer(serializers.Serializer):
    name = serializers.CharField(min_length=1, max_length=10)
    publish = serializers.SerializerMethodField(read_only=True)
    def get_publish(self, obj):
        return {'name': obj.publish.name, 'addr': obj.publish.addr}

    author = serializers.SerializerMethodField(read_only=True)
    def get_author(self, obj):
        authors = obj.author_book.all()
        list_data = []
        for author in authors:
            list_data.append({'name': author.name, 'gender': author.get_gender_display()})
        return list_data

    publish_id= serializers.IntegerField(write_only=True)
    author_id = serializers.ListField(write_only=True)

    # 重建create
    def create(self, validated_data):
        # 弹出author_id
        author = validated_data.pop('author_id')
        book = Book.objects.create(**validated_data)
        book.author_book.add(*author)
        return book

2)修改 - 示例

class BookDetailViewSet(APIView):
    ...
    # 改
    def put(self, request, pk):
        book = Book.objects.get(pk=pk)
        serializer = BookSerializer(instance=book, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({'code': 200,'message': '添加成功','data': serializer.data})
# serializers.py内
class BookSerializer(serializers.Serializer):
    ...
    # 重建update(旧,新)
    def update(self, instance, validated_data):
        # 弹出作者
        author = validated_data.pop('author_id')
        # 清除关系在添加
        instance.author_book.clear()
        instance.author_book.add(*author)
        # 修改Book表
        for key in validated_data:
            setattr(instance, key, validated_data.get(key))
        instance.save()
        return instance

【五】ModelSerializer的使用

1)介绍

  • ModelSerializer与模型表一一对应
  • 可用不重写 create 和 update 便能进行添加修改
  • 序列化与反序列化字段,可通过表映射

2)使用-示例

class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        # 获取Book数据库中所有字段
        # 包括关联的表(publish,author_book)
        fields = '__all__'
        # 获取指定字段
        # fields = ['name', 'publish']
        # 校验书写
        extra_kwargs = {
            'name': {'min_length': 1,'max_length': 10},
            'publish': {'writer_only': True},
            'author_book': {'writer_only': True},
        }

        # 局部钩子
        def validate_name(self, name):
            ...
            return name

        # 全局钩子
        def validate(self, attrs):
            ...
            return attrs

3)定制返回格式-示例

class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        # 获取指定字段
        # 新增的需要注册才能使用
        fields = ['name', 'publish_data','author_book_data']
        # 校验书写
        extra_kwargs = {
            'name': {'min_length': 1, 'max_length': 10},
            'publish_data': {'read_only': True},
            'author_book_data': {'read_only': True},
        }

    publish_data = serializers.SerializerMethodField()
    def get_publish_data(self, obj):
        return {'name': obj.publish.name, 'addr': obj.publish.addr}

    author_book_data = serializers.SerializerMethodField(read_only=True)
    def get_author_book_data(self, obj):
        authors = obj.author_book.all()
        list_data = []
        for author in authors:
            list_data.append({'name': author.name, 'gender': author.get_gender_display()})
        return list_data

标签:格式化,name,author,self,校验,ModelSerializer,publish,serializers,data
From: https://www.cnblogs.com/Mist-/p/18336157

相关文章

  • pydantic做参数校验
    定义一个统一的schema类对提交的业务参数进行格式和数据约束非常有必要,下面使用pydantic来封装此工具;importloggingfrompydanticimportBaseModel,ValidationError,root_validatorclassPydanticValidationError(Exception):def__init__(self,msg):......
  • 格式化字符串(summer2024_fmt)
    参考博客[参考博客]:https://blog.csdn.net/ysy___ysy/article/details/135700140[参考博客]:https://blog.csdn.net/2402_83422357/article/details/139180404戳此切大佬博客https://blog.csdn.net/Morphy_Amo/article/details/122215773https://blog.csdn.net/song_lee/......
  • 对后端返回数据的格式化-日期
    解决方式:1).方式一在属性上加上注解,对日期进行格式化但这种方式,需要在每个时间属性上都要加上该注解,使用较麻烦,不能全局处理。方式二(推荐)**在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式处理点击查看代码/***扩展SpringMVC框......
  • 字符串和格式化输入/输出(解析)
    1:#include<stdio.h>intmain(void){ charname[40]; charsurname[40]; printf("Pleseinputyourfirstname:"); scanf("%s",name); printf("Pleseinputyourlastname"); scanf("%s",surname); printf(&quo......
  • 如何获得 Shiny Chat 的响应来显示格式化的数学方程?
    我试图让这个示例应用程序输出格式化的数学方程。闪亮的聊天教程此处建议自定义响应显示,但我无法获得建议@chat.transform_assistant_response修改格式。我按原样使用下面的代码:@chat.transform_assistant_responsedef_(content:str)->ui.HTM......
  • c语言中数据的格式化输出
     001、输出整型数据,直接输出[root@PC1test]#lstest.c[root@PC1test]#cattest.c#include<stdio.h>intmain(void){printf("[%d]\n",123);return0;}[root@PC1test]#gcctest.c-okkk[root@PC1test]#lskkktest.c[root@PC......
  • SpringCloud网关登录校验
    SpringCloud网关登录校验文章目录SpringCloud网关登录校验1、鉴权思路分析2、网关过滤器3、自定义过滤器3.1、自定义GatewayFilter3.2、自定义GlobalFilter4、登录校验5、微服务获取用户5.1、保存用户到请求头5.2、拦截器获取用户6、OpenFeign传递用户1、鉴权......
  • 计算机组成与体系结构-校验码
    奇偶校验码奇偶校验是一种简单有效的校验方法,这种方法通过在编码中增加一位校验位来使编码中1的个数为奇数(奇校验)或者为偶数(偶校验),只能发现奇数个数据位出错的情况.循环冗余校验码CRC(CyclicRedundancyCheck)循环冗余校验是一种常用的错误检测技术,用于在数据传输过程中......
  • 网关登录校验
    网关登录校验首先写一个demopackagecom.hmall.gateway.filter;importcom.hmall.gateway.config.AuthProperties;importcom.hmall.gateway.util.JwtTool;importlombok.RequiredArgsConstructor;importlombok.extern.slf4j.Slf4j;importorg.springframework.cl......
  • 软考-软件设计师(1)-计算机基础知识点:进制转换、数据编码、内存编址、串并联可靠性、
    场景软考-软件设计师-计算机基础模块高频考点整理。以下为高频考点、知识点汇总,不代表该模块所有知识点覆盖,请以官方教程提纲为准。注:博客:霸道流氓气质-CSDN博客实现知识点进制转换十进制转二进制除以2,反向取余数,直到商为0终止,转换成其他进制同理二进制转十进制其......