rest-framework序列化组件
drf序列化组件之Serializer
新建一个序列化类继承Serializer
在类中写需要序列化的字段
from rest_framework import serializers
class BookSerializers(serializers.Serializer)
name1 = serializers.CharField(source='name')
# 指定source='name' ,表示序列化模型表中的name字段,重名命为name1(name和source='name'指定的name不能重名)
publish=serializers.CharField(source="publish.name")
# 如果要取 出版社的name source='publish.name'
# xx=models.IntegerField(choices=((0,'文学类'),(1,'情感类')),default=1,null=True)
book_type = serializers.CharField(source='get_xx_display')
# source:可以指定字段,也可以指定方法,如果是方法,会执行方法,不用加括号
# SerializerMethodField搭配方法使用
publish_detail=serializers.SerializerMethodField(read_only=True)
# 对应的方法固定写法get_字段名
def get_publish_detail(self,obj):
return {'name':obj.publish.name,'city':obj.publish.city}
# 补充:
# read_only:反序列化时,可以不传
# write_only:序列化时,不显示
在视图中使用序列化的类
- 实例化序列化的类产生对象,在产生对象的时候,传入需要序列化的对象(queryset)
- 对象.data
- return Response(对象.data)
from rest_framework.views import APIView
from rest_framework.response import Response
class Books(APIView):
def get(self,request):
books = models.Book.objects.all()
ret = BookSerializers(books,many=True)
#如果序列化多条,many=True(也就是queryset对象,就需要写)
#如果序列化一条(可以不写),instance是要序列化的对象
return Response(ret.data)
drf序列化组件之ModelSerializer
from rest_framework.serializers import ModelSerializer
class BookSerializers(serializers.ModelSerializer):
class Meta:
model = models.Book
# fields = "__all__" 序列化全部字段
fields=['nid','title','authors','publish'] # 序列化列表中的字段
# exclude=('nid',) # 序列化除了nid外的字段 不能跟fields同时用
# depth = 1 #深度控制,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层
# 在Meta外部,重写某些字段,方式同Serializers
xx=serializers.CharField(source='get_xx_display') # 重写某个字段
publish=serializers.SerializerMethodField()
def get_publish(self,obj):
return obj.publish.name
authors=serializers.SerializerMethodField()
def get_authors(self,obj):
ret=obj.authors.all()
ss=AuthorSerializer(ret,many=True) # 直接拿到序列化后的数据
return ss.data
区别:Serializers:没有指定表模型,ModelSerializers:指定了表模型
序列化组件反序列化
使用继承了Serializers序列化类的对象,反序列化
# 需要在自己写的序列化类中重写create方法
# 在序列化类中
def create(self,validated_data):
ret = models.Book.objects.create(**validated_data)
return ret
# 在视图中
def post(self,request):
# 实例化产生一个序列化类的对象,data是要反序列化的字典
bookser = BookSeriaizer(data=request.data)
if bookser.is_valid():
# 清洗通过的数据
ret = books.create(bookser.validated_data) # 传入
return Response()
使用继承了ModelSerializers序列化类的对象,反序列化
# 在视图中:
def post(self,request):
bookser = BookSerializer(data=request.data)
if bookser.is_valid():
ret = bookser.save()
else:
print(bookser.errors['name'][0])
return Response()
反序列化的校验
# 局部校验
def validate_字段名(self,value):
if value.startswith('sb'):
raise ValidationError('不能以sb开头') # 如果校验失败,抛出ValidationError(抛出的异常信息需要去bookser.errors中取)
return value # 如果校验通过直接return value
# 全局校验
def validate(self,attrs):
print(attrs) # attrs所有校验通过的数据,是个字典
if attrs.get('price')!=attrs.get('xx'):
raise exceptions.ValidationError('name和price相等,不正常')
# 如果校验失败,抛出ValidationError
return attrs # 如果校验通过直接return attrs