django自带的序列化组件(了解,不好控制)
from django.core import serializers from django.core import serializers def test(request): book_list = Book.objects.all() ret = serializers.serialize("json", book_list) return HttpResponse(ret)
# 会把所有的字段都取出来,很多无用信息,不好控制
rest_framework的serializers组件
# 新建一个py文件,写上需要序列化的字段 from rest_framework import serializers from apps import models class bookser(serializers.Serializer): name = serializers.CharField() publish = serializers.CharField() # 在view里序列化表 from rest_framework.response import Response from apps import models from rest_framework.views import APIView from apps.app01_serializer.app01_ser import Bookser class test(APIView): def get(self,request,*args,**kwargs): book_obj = models.book.objects.all() books = Bookser(book_obj,many=True) return Response(books.data)
得到页面:注意要在settings的app里注册rest_framework
只序列化得到了需要的字段
source
序列化字段的名字和表中的一一对应,如果不对应则无法序列化,我们可以加source参数 class bookser(serializers.Serializer): name = serializers.CharField() name5 = serializers.CharField(source='name') 注意:source不能和定义的字段名一样,不然会报错 publish = serializers.CharField() # 如果book表外键关联publish,我们想要获取publish的city class bookser(serializers.Serializer): name5 = serializers.CharField(source='name') publish = serializers.CharField(soucre='publish.city') # source不但可以指定一个字段,还可以指定一个方法 models.py from django.db import models class book(models.Model): name = models.CharField(max_length=16) def test(self): return 'xxx' book_ser.py文件 class bookser(serializers.Serializer): name = serializers.CharField() xxx = serializers.CharField(source = 'test')
拿字段的中文'get_字段名_display' models.py xx = models.IntegerField(choices=((0,'文学类'),(1,'情感类')),default=1)
book_ser.py文件
# xx = serializers.CharField(source = 'get_字段名_display')
xx = serializers.CharField(source = 'get_xx_display')
ModelSerializer
book_ser.py from rest_framework import serializers from apps import models class Bookser(serializers.Serializer): name = serializers.CharField() publish = serializers.CharField(source='publish.name') # 指定ModelSerializer之后,可以对应一个方法,返回什么内容,publish_detail就是什么内容 publish_detail = serializers.SerializerMethodField() # 对应的方法是固定写法(get_字段名) def get_publish_detail(self,obj): return {'name':obj.publish.name,'city':obj.publish.city}
class AuthorsSerialiser(serializers.Serializer):
name = serializers.CharField()
age = serializers.CharField()
class Bookser(serializers.Serializer): name = serializers.CharField() publish = serializers.CharField(source='publish.name') authors = serializers.SerializerMethodField() def get_authors(self,obj): authors_ser = AuthorsSerialiser(obj.authors.all(),many=True) return authors_ser.data
write_only和read_only
# write_only 序列化的时候不显示 # read_only 反序列化的时候不传 序列化book表时,字段price可以不显示,只需定义 price = serializers.CharField(write_only=Ture)
反序列化
# 序列化类中 apps_ser.py class book_ser(serializers.Serializer): ... ... def create(self,validated_data): ret = model.Book.objects.create(**validated_data) return ret # 在视图view.py def post(self,request): bookser = BookSerializer(data=request.data) if bookser.isvalid(): ret = bookser.create(bookser.validated_data) return Response()
反序列化中的ModelSerializer
class BookSerializers(serializers.ModelSerializer): class Meta: model = models.Book # fields = "__all__" fields=['nid','title','authors','publish'] # exclude=('nid',) #不能跟fields同时用 # depth = 1 #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层 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
view.py def post(self,request): # 实例化产生一个序列化对象,data是要反序列化的字典 bookser = BookSerializer(data=request.data) if bookser.is_valid(): # 数据通过清洗 bookser.save() return Response()
反序列化中的效验(局部效验和全局效验)
# 局部效验name字段 def validate_name(self,value): if value.startswith('sb'): raise ValidationError('不能以sb'开头) return value # 全局效验 def validate(self,attrs): if attrs.get('name')==attrs.get('price'): raise ValidationErroe('name和price相等,不正常') return attrs view.py def post(self,request): # 实例化产生一个序列化对象,data是要反序列化的字典 bookser = BookSerializer(data=request.data) if bookser.is_valid(raise_exception=True): # 通过清洗数据 # 数据通过清洗 bookser.save() else: print(bookser.error['name'][0]) return Response()