Django自带序列化组件
这是原生的django序列化组件 但是因为只能对所有的内容进行序列化 ,拓展性太差,所以我们基本启弃用
from django.core import serializers def test(request): book_list = Book.objects.all() ret = serializers.serialize("json", book_list) return HttpResponse(ret)
drf序列化的两种方式
第一种: Serializers
1 新建一个序列化类继承Serializer
2 在类中写要序列化的字段
在视图中使用序列化的类
1 实例化序列化的类产生对象,在产生对象的时候,传入需要序列化的对象(queryset)
2 对象.data
3 return Response(对象.data)
高级用法:
source:可以指定字段(name publish.name),可以指定方法,
SerializerMethodField搭配方法使用(get_字段名字)
publish_detail=serializers.SerializerMethodField(read_only=True)
def get_publish_detail(self,obj):
return {'name':obj.publish.name,'city':obj.publish.city}
read_only:反序列化时,不传
write_only:序列化时,不显示
from rest_framework import serializers class AuthorSerializer(serializers.Serializer): name=serializers.CharField() age=serializers.CharField() class BookSerializer(serializers.Serializer): # #指定source='name' ,表示序列化模型表中的name字段,重名命为name5(name和source='name'指定的name不能重名) name5=serializers.CharField(source='name') # #write_only 序列化的时候,该字段不显示 # #read_only 反序列化的时候,该字段不传 price=serializers.CharField(write_only=True) # #如果要取 出版社的city source='publish.city' publish=serializers.CharField(source='publish.name') # #source不但可以指定一个字段,还可以指定一个方法 # book_type = serializers.CharField(source='get_xx_display',read_only=True) # #序列化出版社的详情,指定SerializerMethodField之后,可以对应一个方法,返回什么内容,publish_detail就是什么内容 publish_detail=serializers.SerializerMethodField(read_only=True) # #对应的方法固定写法get_字段名 def get_publish_detail(self,obj): # print(type(obj)) return {'name':obj.publish.name,'city':obj.publish.city} # # #返回所有作者信息 authors=serializers.SerializerMethodField(read_only=True) def get_authors(self,obj): # return [ {'name':author.name,'age':author.age} for author in obj.authors.all()] authorser=AuthorSerializer(obj.authors.all(),many=True) return authorser.data def create(self, validated_data): ret=models.Book.objects.create(**validated_data) return ret
第二种: ModelSerialzers
继承该类就指定了表模型
class Meta:
model=表模型
1要显示的字段
fields='__all__'
fields=('id','name')(注释:列表元组均可以)
2要排除的字段
exclude=('name')
3深度控制
depth=1
4重写某个字段
在Meta外部,重写某些字段,方式同Serializers
from rest_framework import serializers class AuthorSerializer(serializers.Serializer): name=serializers.CharField() age=serializers.CharField() from rest_framework import serializers from rest_framework import exceptions from rest_framework.exceptions import ValidationError from app01 import models class BookSerializer(serializers.ModelSerializer): class Meta: model=models.Book # fields=('nid','name') #不能跟fields同时使用 # exclude=['name',] fields=('__all__') #深度是1,官方建议不要超过10,个人建议不要超过3 # depth=1 xx=serializers.CharField(source='get_xx_display') authors=serializers.SerializerMethodField() def get_authors(self,obj): ret=AuthorSerializer(instance=obj.authors.all(),many=True) return ret.data name=serializers.CharField() #反序列化的校验(局部校验,全局校验) def validate_name(self,value):
反序列化
-使用继承了Serializers序列化类的对象,反序列化
-在自己写的序列化类中重写create方法
-重写create方法,实现序列化
-在序列化类中:
def create(self, validated_data): ret=models.Book.objects.create(**validated_data) return ret
-在视图中:
def post(self,request): bookser=BookSerializer(data=request.data) if bookser.is_valid(): ret=bookser.create(bookser.validated_data) return Response()
反序列化的校验
validate_字段名(self,value):
如果校验失败,抛出ValidationError(抛出的异常信息需要去bookser.errors中取)
如果校验通过直接return value
validate(self,attrs)
attrs所有校验通过的数据,是个字典
如果校验失败,抛出ValidationError
如果校验通过直接return attrs
def validate_name(self,value): print(value) # raise exceptions.ValidationError('不能以sb开头') if value.startswith('sb'): raise ValidationError('不能以sb开头') return value def validate(self,attrs): print(attrs) # if attrs.get('price')!=attrs.get('xx'): # raise exceptions.ValidationError('name和price相等,不正常') return attrs