Django自带序列化组件
这是原生的django序列化组件 但是因为只能对所有的内容进行序列化 ,拓展性太差,所以我们基本启弃用
from django.core import serializersdef 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 serializersclass 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 serializersclass AuthorSerializer(serializers.Serializer): name=serializers.CharField() age=serializers.CharField() from rest_framework import serializersfrom rest_framework import exceptionsfrom rest_framework.exceptions import ValidationErrorfrom app01 import modelsclass 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 valuevalidate(self,attrs) attrs所有校验通过的数据,是个字典 如果校验失败,抛出ValidationError 如果校验通过直接return attrsdef 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