drf---序列化
序列化总结
1、序列化类 (做序列化):多条一定要写 many = True
2、序列化校验:ser.is_valid() 就会走校验
3、反序列化保存
新增:
ser = BookSerializer(data=request.data)
ser.save()--->触发 序列化类中的 create---》为什么?内部做了判断:根据是否有instance
create中,自己写保存到哪个表中:有数据--》保存到某个表中
修改:
ser = BookSerializer(instance=待修改对象,data=request.data)
ser.save()--->触发 序列化类中的 update---》为什么?内部做了判断:根据是否有instance
update中,有待修改对象,有数据---》修改完保存即可--》两种方式
反射
反序列化之更新
views
from .models import User from rest_framework.response import Response from rest_framework.views import APIView from .serializer import UserSerializer class UserView(APIView): def get(self, request): # 获取数据 user = User.objects.all() res = UserSerializer(instance=user,many=True) return Response(res.data) def post(self, request): #添加数据 print(request.data) res = UserSerializer(data=request.data) if res.is_valid(): res.save() return Response({'code':10,'msg':'保存成功'}) else: return Response({'code':11,'msg':res.errors}) class Userdetial(APIView): def get(self, request, pk): #获取单个值 user = User.objects.filter(pk=pk).first() #序列化 res = UserSerializer(instance=user) return Response(res.data) def delete(self, request, pk): #找到要删除的数据 user = User.objects.filter(pk=pk).delete() return Response({'code':10,'msg':'删除成功'}) def put(self, request, pk): #修改数据 user = User.objects.filter(pk=pk).first() res = UserSerializer(instance=user,data = request.data) #将前端获取的数据和旧的数据传过去 if res.is_valid(): res.save() return Response({'code':10,'msg':'修改成功'}) else: return Response({'code':11,'mag':res.errors})
序列化类
from rest_framework import serializers from .models import User from rest_framework.exceptions import ValidationError ''' -姓名不能以 sb开头 -姓名最大8位,最小3位 -密码不能超过100,最低不能低于10 ''' class UserSerializer(serializers.Serializer): name = serializers.CharField(max_length=8,min_length=3,required=False) age = serializers.IntegerField(required=False) password = serializers.CharField(max_length=100,min_length=10,required=False) hobby = serializers.CharField(required=False) #局部钩子 def validate_name(self,value): if value.startswith('sb'): raise ValidationError('不能以sb开头') return value def create(self, validated_data): user = User.objects.create(**validated_data) return user def update(self, instance, validated_data): #方法一 instance.name = validated_data['name'] instance.password = validated_data['password'] instance.hobby = validated_data['hobby'] instance.age = validated_data['age'] instance.save() # 方法二 # #用反射的方法将数据循环 # for i in validated_data: # res = setattr(instance,i,validated_data.get(i)) #因为反射没有返回值,所以无法打印 # instance.save() return instance
高级用法source(了解)
字段类的属性
如下写法就能修改序列化的字段
方法一(在序列化类中):
方法二(在序列化类中跨表查询):
# 用法二 :跨表查询
publish = serializers.CharField(source='publish.name')
# 自动对应成出版社的名字 可以通过 . 跨表查询
用法三(序列化字段中查询,在模型中加入方法)
高级用法定制字段
定制返回的字段格式
方案一(使用SerializerMethodField 定制):
在序列化类中
方案二:在表模型中定制
表模型
序列化类
多表关联序列化和反序列化
以后一个序列化类,想即做序列化,又做反序列化,会出现的问题:
字段不匹配,尤其是多表关联的字段
有的字段即做序列化,又做反序列化
name = serializers.CharField()
price = serializers.IntegerField()
有的字段只用序列化(read_only表示 只做序列化)
publish_dict = serializers.DictField(read_only=True) # 只做序列化
author_list = serializers.ListField(read_only=True) # 只做序列化
有的字段只做反序列化(write_only),是什么类型取决于前端传入的格式是什么样
publish_id = serializers.IntegerField(write_only=True) # 反序列化
authors = serializers.ListField(write_only=True) # 反序列化
保存方法需要重写
def create(self, validated_data): # {"name":"11111","price":999,"publish":1,"authors":[1,2]}
authors=validated_data.pop('authors')
book = Book.objects.create(**validated_data)
增加中间表的记录:图书和作者的关系
book.authors.add(*authors) # 向中间表中存入:这个图书关联的做作者
return book
##也可以使用笨办法:
序列化用一个序列化类
反序列化换另一个序列化类
反序列化校验总结
什么情况用反序列化校验?
做反序列化的时候,才用----》校验前端传入的数据
三层:
字段自己:字段类属性---》可控制的比较小
局部钩子:单个字段校验
全局钩子:多个字段同时校验
作业
视图层
from django.shortcuts import render # Create your views here. from rest_framework.views import APIView from rest_framework.response import Response from .models import Book, Publish, Author from .serializer import BookSerializer class Bookview(APIView): # 查找全部数据 def get(self, request, *args, **kwargs): book_list = Book.objects.all() # 序列化数据给出去 res = BookSerializer(book_list, many=True) return Response({'code': 10, 'msg': '查询成功', 'result': res.data}) # 创建数据 def post(self, request, *args, **kwargs): # 反序列化传入 res = BookSerializer(data=request.data) if res.is_valid(): res.save() return Response({'code': 10, 'msg': '添加成功'}) else: return Response({'code': 11, 'msg': res.errors}) class BookDetialview(APIView): def get(self, request, pk, *args, **kwargs): book_list = Book.objects.filter(pk=pk).first() #序列化 res = BookSerializer(book_list) return Response({'code': 10, 'msg': '查询成功', 'result': res.data}) def put(self, request, pk, *args, **kwargs): #修改数据 book_list = Book.objects.filter(pk=pk).first() res = BookSerializer(instance=book_list,data=request.data) if res.is_valid(): res.save() return Response({'code':11,'msg':'修改成功','result':res.data}) else: return Response({'code':12,'msg':'修改失败'}) def delete(self, request, pk, *args, **kwargs): Book.objects.filter(pk=pk).delete() return Response({'code': 10, 'msg': '删除成功'})
模型层
from django.db import models # Create your models here. '''图书表、作者表、出版社表''' class Book(models.Model): name = models.CharField(max_length=32) price = models.IntegerField(max_length=32) publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE) authors = models.ManyToManyField(to='Author') def publish_dict(self): return {'name':self.publish.name,'addr':self.publish.addr} def author_list(self): l=[] for i in self.authors.all(): l.append({'name':i.name,'age':i.age,'sex':i.sex}) return l class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() sex = models.CharField(max_length=32)
序列化类
from rest_framework import serializers from .models import Book class BookSerializer(serializers.Serializer): #book表中的数据即做序列化又做反序列化 name = serializers.CharField() price = serializers.IntegerField() #跨表中的图书表和作者表做序列化,用来查询 publish_dict = serializers.DictField(read_only=True) author_list = serializers.ListField(read_only=True) #跨表中图书表和作者表做反序列化,用来创建及更新 publish_id = serializers.IntegerField(write_only=True) authors = serializers.ListField(write_only=True) def create(self, validated_data): authors =validated_data.pop('authors') book =Book.objects.create(**validated_data) book.authors.add(*authors) return book def update(self, instance, validated_data): authors = validated_data.pop('authors') #通过反射 for i in validated_data: rse = setattr(instance,i,validated_data.get(i)) instance.authors.set(authors) instance.save() return instance
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能