序列化组件

一.Django自带序列化组件

    -非常难用,一般不使用

二.rest-framework序列化组件

from rest_framework.response import Response

return Response(response)

#以后建议使用这种方法,但是一定要注册一下rest_framework

1.rest-framework序列化之Serializer

#新建一个py文件    Myserializer.py
①写一个类,继承Serializer
单独创建一个py文件,建一个类在类中写要序列化的字段
from rest_framework.serializers import Serializer
from rest_framework import serializers

#序列化Author表
class AuthorSerializer(Serializer):
    id = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()

#序列化book表
class BookSerializer(Serializer):
    #序列化表中的某些字段,字段名必须对应上
    id = serializers.CharField()
    name = serializers.CharField()
    #如果要是返回的数据字段名与表中的字段名不一致,可以进行如下设置
    #title = serializers.CharField(source='name')
    price = serializers.CharField()
    #得到关系表中的指定字段
    publish_name = serializers.CharField(source='publish.name')
    
    #source 不但可以指定表模型的字段,还可以指定表模型的方法
    #指定表模型的方法时,执行该方法,并将返回值赋给命名的变量
    
    #获取publish的所有信息,id,name,city,email
    #SerializerMethodField,必须配合方法使用  get_字段名(self,obj),obj要序列化的对象
    #方法的返回值会赋值给publish
    publish = serializers.SerializerMethodField()
    def get_publish(self,obj):  #obj为book对象 get_字段名 要与上面那行属性名相同
        return {'id':obj.publish.pk,'name':obj.publish.name}
    
    #获取所有作者的详情
    #SerializerMethodField对应的方法中还可以继续使用其他的序列化类
    authors = serializers.SerializerMethodField()
    def get_authors(self,obj):
        author_list = obj.authors.all()
        author_ser = AuthorSerializer(author_list,many=True)
        return author_ser.data


②在View.py中使用
from rest_framework.response import Response
from rest_framework.views import APIView
from app1.models import *
from app1.Myserializer import BookSerializer
class BooksView(APIView):
    def get(self,request,*args,**kwargs):
        response={'status':100,'msg':'获取成功'}
        book_list = Book.objects.all()
        #使用:实例化BookSerializer类,把要序列化的数据传入(queryset对象)
        #如果要序列queryset对象,一定要加 many=True
        book_ser = BookSerializer(book_list,many=True)
        response['data'] = book_ser.data  #book_ser.data序列化后的数据
        return Response(response)

2.rest-framework序列化之ModelSerializer

#新建一个py文件    Myserializer.py
①写一个类,继承ModelSerializer,可以直接指定要序列化的表模型
from rest_framework import serializers
from app1 import models

#在类中写如下代码
class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        #指定要序列化author这个表
        model = models.Author
        #序列化所有字段
        fields = '__all__'

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        #指定要序列化book这个表
        model = models.Book

        #指定要序列化的字段
        # fields = ['id','name']

        #序列化所有字段
        fields = '__all__'

        #指定不显示的字段(注意:不能跟fields连用)
        # exclude = ['name','price']

        #深度,官方建议写10个,个人建议最多写3,不太建议使用
        #写了这个就不用也下面的代码以及AuthorSerializer这个类,它会直接把与其连表的所有数据拿出来
        depth = 1  
        
    #获取publsih某个字段
    # publish_name = serializers.CharField(source='publish.name')

    #获取publish的所有信息,id,name,city,email
    #SerializerMethodField,必须配合方法使用  get_字段名(self,obj),obj要序列化的对象
    publish = serializers.SerializerMethodField()
    def get_publish(self,obj):  #obj为book对象
        return {'id':obj.publish.pk,'name':obj.publish.name}
    
    #获取author的所有信息
    authors = serializers.SerializerMethodField()
    def get_authors(self,obj):
        author_list = obj.authors.all()
        author_ser = AuthorSerializer(author_list,many=True)
        return author_ser.data

②在View.py中使用
from rest_framework.response import Response
from rest_framework.views import APIView
from app1.models import *
from app1.Myserializer import BookSerializer
class BooksView(APIView):
    def get(self,request,*args,**kwargs):
        response={'status':100,'msg':'获取成功'}
        book_list = Book.objects.all()
        #使用:实例化BookSerializer类,把要序列化的数据传入(queryset对象)
        #如果要序列queryset对象,一定要加 many=True
        book_ser = BookSerializer(book_list,many=True)
        response['data'] = book_ser.data  #book_ser.data序列化后的数据
        return Response(response)

3.查看单本书

#路由层
url(r'^books/(?P<pk>d+)$', views.BookView.as_view())

#视图函数层
#获取单个book接口
class BookView(APIView):
    def get(self,request,pk,*args,**kwargs):
        response = {'status':100,'msg':'获取成功'}

        #取到pk为传入的pk的书,得到的是book对象
        book = Book.objects.filter(pk=pk).first()

        #要序列化单条,many=False
        book_ser = BookSerializer(instance=book,many=False)

        response['data'] = book_ser.data

        return Response(response)

4.新增一本书

#测接口用postman

class BooksView(APIView):
    #添加一本书的接口
    def post(self,request,*args,**kwargs):
        response = {'status': 100, 'msg': '新增成功'}
        #序列化类的反序列化功能
        try:
            book_ser = BookSerializer(data=request.data)
            #必须要校验
            if book_ser.is_valid():
                book_ser.save()
                response['data'] = book_ser.data
            else:
                response['msg'] = book_ser.errors
        except Exception as e:
            response['msg'] = str(e)
        return Response(response)

    
'''
反序列化之局部,全局钩子(序列化的类一定是继承ModelSerializer的类)

from rest_framework.exceptions import ValidationError
class BookSerializer(serializers.ModelSerializer):
    
    #局部钩子函数,对局部字段进行校验
    def validate_name(self,value):
        if value.startswith('sb'):
            raise ValidationError('书名不能以sb开头')
        else:
            return value

    #全局钩子函数,对全局字段进行校验
    def validate(self,attr): #attr字典
        name=attr.get('name')
        price=attr.get('price')
        if name != price:
            raise ValidationError('错了')
        else:
            return attr
'''

5.修改某本书

class BookView(APIView):
    # 修改某本书的接口
    def put(self, request, pk, *args, **kwargs):
        response = {'status': 100, 'msg': '修改成功'}
        book = Book.objects.filter(pk=pk).first()

        #明确要修改哪一本书,要明确instance
        book_ser = BookSerializer(instance=book, data=request.data)
        # 必须要校验
        if book_ser.is_valid():
            book_ser.save()
            response['data'] = book_ser.data
        else:
            response['msg'] = book_ser.errors

        return Response(response)

6.删除某本书

class BookView(APIView):
    # 删除某本书的接口
    def delete(self,request,pk):
        response = {'status': 100, 'msg': '删除成功'}
        book =Book.objects.filter(pk=pk).first()
        #删除
        book.delete()
        response['data'] = ''
        
        return Response(response)
原文地址:https://www.cnblogs.com/lizeqian1994/p/10689637.html