rest_framework序列化组件

一、Django自带的序列化组件  ==》对象序列化成json格式的字符串

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序列化之Serializer

下面用一个例题来说明序列化组件的具体使用

models部分

 1 from django.db import models
 2 
 3 # Create your models here.
 4 
 5 
 6 class Book(models.Model):
 7     title=models.CharField(max_length=32)
 8     price=models.IntegerField()
 9     pub_date=models.DateField()
10     publish=models.ForeignKey("Publish")
11     authors=models.ManyToManyField("Author")
12     def __str__(self):
13         return self.title
14 
15 class Publish(models.Model):
16     name=models.CharField(max_length=32)
17     email=models.EmailField()
18     def __str__(self):
19         return self.name
20 
21 class Author(models.Model):
22     name=models.CharField(max_length=32)
23     age=models.IntegerField()
24     def __str__(self):
25         return self.name
View Code

views部分

 1 from rest_framework.views import APIView
 2 from rest_framework.response import Response
 3 from .models import *
 4 from django.shortcuts import HttpResponse
 5 from django.core import serializers
 6 
 7 
 8 from rest_framework import serializers
 9 
10 class BookSerializers(serializers.Serializer):  ===》这里的Serializer是大写开头
11     title=serializers.CharField(max_length=32)
12     price=serializers.IntegerField()
13     pub_date=serializers.DateField()
14     publish=serializers.CharField(source="publish.name")
15     #authors=serializers.CharField(source="authors.all")
16     authors=serializers.SerializerMethodField()  ==》这里用这个下面需要跟上get + 字段
17     def get_authors(self,obj):
18         temp=[]
19         for author in obj.authors.all():
20             temp.append(author.name)
21         return temp
22   #此处可以继续用author的Serializers,
23   # def get_authors(self,obj):
24     #     ret=obj.authors.all()
25     #     ss=AuthorSerializer(ret,many=True)
26     #     return ss.data
27 
28 class BookViewSet(APIView):
29 
30     def get(self,request,*args,**kwargs):
31         book_list=Book.objects.all()
32         # 序列化方式1:
33         # from django.forms.models import model_to_dict
34         # import json
35         # data=[]
36         # for obj in book_list:
37         #     data.append(model_to_dict(obj))
38         # print(data)
39         # return HttpResponse("ok")
40 
41         # 序列化方式2:
42         # data=serializers.serialize("json",book_list)
43         # return HttpResponse(data)
44 
45         # 序列化方式3:
46         bs=BookSerializers(book_list,many=True)     #many=True代表有多条数据,如果只有一条数据,many=False
47         return Response(bs.data)
48      # 序列化方式4: 
49       # ret=models.Book.objects.all().values('nid','title')
50      # dd=list(ret)
51         # return HttpResponse(json.dumps(dd))

注意:

source 如果是字段,会显示字段,如果是方法,会执行方法,不用加括号(authors=serializers.CharField(source='authors.all'))

如在模型中定义一个方法,直接可以在在source指定执行

二、rest_framework序列化之ModelSerializer

 1 class BookSerializers(serializers.ModelSerializer):
 2     class Meta:
 3         model = models.Book
 4         # fields = "__all__"
 5         fields=['nid','title','authors','publish']
 6         # exclude=('nid',)   #不能跟fields同时用
 7         # depth = 1    #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层
 8     publish=serializers.SerializerMethodField()
 9     def get_publish(self,obj):
10         return obj.publish.name
11     authors=serializers.SerializerMethodField()
12     def get_authors(self,obj):
13         ret=obj.authors.all()
14         ss=AuthorSerializer(ret,many=True)
15         return ss.data

三、序列化组件之请求数据校验和保存功能

 1 class BookSerializers(serializers.ModelSerializer):
 2     class Meta:
 3         model=Book
 4         fields="__all__"
 5 
 6 #————————
 7 class BookView(APIView):
 8 
 9     def post(self, request):
10 
11         # 添加一条数据
12         print(request.data)
13 
14         bs=BookSerializers(data=request.data)
15         if bs.is_valid():
16             bs.save()  # 生成记录
17             return Response(bs.data)
18         else:
19 
20             return Response(bs.errors)

通过源码查看留的校验字段的钩子函数:

 1 #is_valid---->self.run_validation-(执行Serializer的run_validation)-->self.to_internal_value(data)---(执行Serializer的run_validation:485行)
 2 def validate_title(self, value):
 3         from rest_framework import exceptions
 4         raise exceptions.ValidationError('看你不顺眼')
 5         return value
 6 
 7 #全局
 8 def validate(self, attrs):
 9     from rest_framework import exceptions
10     if attrs.get('title')== attrs.get('title2'):
11         return attrs
12     else:
13         raise exceptions.ValidationError('不想等啊')

序列化组件源码分析

序列化组件,先调用__new__方法,如果many=True,生成ListSerializer对象,如果为False,生成Serializer对象
序列化对象.data方法--调用父类data方法---调用对象自己的to_representation(自定义的序列化类无此方法,去父类找)
Aerializer类里有to_representation方法,for循环执行attribute = field.get_attribute(instance)
再去Field类里去找get_attribute方法,self.source_attrs就是被切分的source,然后执行get_attribute方法,source_attrs
当参数传过去,判断是方法就加括号执行,是属性就把值取出来


原文地址:https://www.cnblogs.com/Roc-Atlantis/p/9794762.html