drf 之序列化组件

序列化

  把Python中对象转换为json格式字符串

反序列化

  把json格式转为为Python对象。

用orm查回来的数据都是都是一个一个的对象, 但是前端要的是json格式字符串。

序列化两大功能:

  对请求数据进行验证

  对Queryset对象进行序列化

一、Django自带序列化组件

  略

二、rest framework序列化之Serializer

使用方式如下:

建表 models.py

from django.db import models

# Create your models here.


class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()
    pub_date=models.DateField()
    publish=models.ForeignKey("Publish")
    authors=models.ManyToManyField("Author")
    def __str__(self):
        return self.title

class Publish(models.Model):
    name=models.CharField(max_length=32)
    email=models.EmailField()
    def __str__(self):
        return self.name

class Author(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField()
    def __str__(self):
        return self.name

views

写一个restframework接口拿到数据(所有图书)

方式一:如果没有序列化组件的话,要先转成字典,然后再用json.dumps()再转。

方式二:用序列化组件。

首先你要序列化谁,先写一个类。这个类继承一个东西,然后用的时候,在视图类中直接用这个类生成一个对象。

from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response

# Create your views here.

from api import models

# 想用这个类,需要导入
from api.MySerializer import BookSerializer

class BookView(APIView):

    def get(self,request,*args,**kwargs):
        ret = {
            'code':100,
            'msg':'成功了'
        }
        books = models.Book.objects.all()
        # 第一个参数是要序列化的对象,如果序列化多条,必须指定many=True
        books_ser = BookSerializer(instance=books,many=True)
        # 当序列化的对象是单个对象的时候many=False book = models.Book.objects.all().first()
        # books_ser.data  就是序列化后的结果 是个字典
        print(books_ser.data)
        ret['books']=books_ser.data
        # return Response(books_ser.data)
        return Response(ret)

写的格式化的类在另外的文件夹或文件:

# 自己写一个序列化的类
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
    # 序列化哪个字段,必须跟数据库字段一样,都想序列化就一个一个排着写
    id = serializers.CharField()
    title = serializers.CharField()
    price = serializers.CharField()

在线格式化json

https://www.json.cn

获取一本id为3的书  http://127.0.0.1:8000/book/3

路由:

from api import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^books/$', views.BookView.as_view()),
    url(r'^book/(?P<id>d+)$', views.Book.as_view()),
]

视图:

from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response

# Create your views here.

from api import models

# 想用这个类,需要导入
from api.MySerializer import BookSerializer

class BookView(APIView):

    def get(self,request,*args,**kwargs):
        ret = {
            'code':100,
            'msg':'成功了'
        }
        books = models.Book.objects.all()
        # 第一个参数是要序列化的对象,如果序列化多条,必须指定many=True
        books_ser = BookSerializer(instance=books,many=True)
        # 当序列化的对象是单个对象的时候many=False book = models.Book.objects.all().first()
        # books_ser.data  就是序列化后的结果 是个字典
        print(books_ser.data)
        ret['books']=books_ser.data
        # return Response(books_ser.data)
        return Response(ret)


class Book(APIView):
    def get(self,requst,id):
        ret = {
            'code': 100,
            'msg': '成功了'
        }

        book = models.Book.objects.filter(pk=id).first()
        book_ser = BookSerializer(instance=book,many=False)
        ret['book']=book_ser.data
        return Response(book_ser.data)

如果序列化加个publish字段  (外键关联的)

拿到的是  "publish": "Publish object" 

如果想显示出版社的名字,拿到出版社的id 

可以通过source来改名!

  变量名和source指定的值不能一样。

  source还支持继续点(字段)还支持方法

序列化的类:

# 自己写一个序列化的类
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
    # 序列化哪个字段,必须跟数据库字段一样,都想序列化就一个一个排着写
    id = serializers.CharField()


    # title = serializers.CharField()
    name = serializers.CharField(source='title')

    price = serializers.CharField()

    publish_name = serializers.CharField(source='publish.name')
    publish_id = serializers.CharField(source='publish.pk')

拿出出版社所有的东西:SerializerMethodField()

意思是支持SerializerMethodField()这个方法,并且把返回值赋值给字段

固定写法:get_这个字段名字,里面有个参数obj,这个obj就是当前对象。

# 自己写一个序列化的类
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
    # 序列化哪个字段,必须跟数据库字段一样,都想序列化就一个一个排着写


    publish_dic = serializers.SerializerMethodField()

    def get_publish_dic(self, obj):
        #意思是支持SerializerMethodField()这个方法,并且把返回值赋值给publish_dic
        return {'id':obj.publish.pk,'name':obj.publish.name,'email':obj.publish.email}

多对多的表关系:  

原文地址:https://www.cnblogs.com/zhangrenguo/p/10507156.html