rest-framework之序列化组件

一:django自带序列化组件

Django内置的serializers(把对象序列化成json字符串)
from django.core import serializers
def test(request):
    book_list = models.Book.objects.all()
    ret = serializers.serialize('json', book_list)
    return HttpResponse(ret)

二: rest-framework序列化之Serializer

Serializer各种方法即单表查询

from django.db import models

# Create your models here.

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()

    publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
    authors=models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()
    def __str__(self):
        return self.name
    def test(self):
        return self.email
models.py

在app01中创建一个新的py文件,mySer.py

#!/usr/bin/env python 
# -*- coding: utf-8 -*-
from rest_framework import serializers


class BookSerializer(serializers.Serializer):
    # 重命名
    thisname = serializers.CharField(source='name')
    price = serializers.CharField()
    # 在source不光能指定字段的名字,还能指定函数的名字
    test = serializers.CharField(source='publish.test')

    # 在source后这样写,能拿到表中的任意字段
    # publish = serializers.CharField(source='publish.city')
    # source加.内容,判断点后面的是一个字段还是一个可执行的函数,
    # 是函数就加括号执行,是字段,取出对应的值给publish

    # SerializerMethodField可以制定一个方法
    publish = serializers.SerializerMethodField()
    #方法名:叫get_字段名,要传参数,参数是:当前book对象
    def get_publish(self, obj):
        dic = {'name': obj.publish.name,'email':obj.publish.email}
        return dic
mySer.py

详解如下

来到视图对象

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from app01 import models
from app01.mySer import BookSerializer
from django.http import JsonResponse


# Create your views here.

# Django内置的serializers(把对象序列化成json字符串)
# from django.core import serializers
# def test(request):
#     book_list = models.Book.objects.all()
#     ret = serializers.serialize('json', book_list)
#     return HttpResponse(ret)

class Books(APIView):
    def get(self, request, *args, **kwargs):
        ret = models.Book.objects.all()  # queryset对象
        # 生成一个序列化对象,传参数
        # 序列化多条,记住many=True
        book_ser = BookSerializer(ret, many=True)

        return JsonResponse(book_ser.data, safe=False)
views.py

总结以上内容

-1 重命名:用source:xx = serializers.CharField(source='name')
            -2 取出出版社名字:
                方式一:
                    -在模型表中重写__str__方法
                    -publish=serializers.CharField()
                方式二:
                    -用source
                    -拿出出版社的城市
                    -publish=serializers.CharField(source='publish.city')
        
                *****如果不指定source,字段必须对应起来,如果指定了source,字段可以任意命名
            -source 可以指定字段,也可也指定方法
                publish.test这是个方法,会执行该方法,并拿到返回结果
                test = serializers.CharField(source='publish.test')
            -3 SerializerMethodField,可以指定一个方法
                publish=serializers.SerializerMethodField()
                # 方法名:叫get_字段名,要传参数,参数是:当前book对象
                def get_publish(self,obj):
                    # obj 是当前book对象
                    dic={'name':obj.publish.name,'email':obj.publish.email}
                    return dic
                -方法内部可以继续用其他的序列化类
        -ModelSerializer
            -必须在类中写
            class Meta:
                model=指定表
                # fields = '__all__'
                # 指定只取这两个字段
                fields = ['nid','name']
                # 去掉指定的字段
                # exclude=['publish','authors']
                # fields,跟exclude不能连用
                # 指定深度,就是跨几个表(官方建议小于10,我给你的建议小于3)
                # depth = 2
            
Serializer小总结

Serializer序列化的跨表查询

 

在postman中的运行效果

效果不好的话将代码复制到www.json.cn中,可以折叠,看起来更清晰,即

如果不想写for循环,还有一种方法

在mySer中写上

# 作者的序列化的类
class AuthorSerializer(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()

在图书序列化的类下面 写方法

# 通过上面的作者的序列化的类来实现
    def get_authors(self, obj):
        auths = obj.authors.all()
     
     #可以继续用序列化来处理
auth_ser
=AuthorSerializer(auths,many=True) return auth_ser.data

这样,在视图函数中一样能拿到图书的作者们

三:serializers.ModelSerializer序列化方法

 

第一种方式(类中类)

在mySer.py中

from app01.models import Book
class BookSerializer(serializers.ModelSerializer):
    # 不用按字段,直接序列化到表模型
    #必须写一个内部内,名字必须交Meta
    class Meta:
        model=Book
        fields='__all__' #闹出book表的所有字段

 postman运行结果会出现这样,publish和authors都是id

那么在

    #重写属性
    publish=serializers.CharField(source='publish.name')

 

 在mySer中写

 authors=serializers.SerializerMethodField()
    def get_authors(self,book):
        auths=book.authors.all()
        auth_ser=AuthorSerializer(auths,many=True)
        return auths.data

 第二种方式:depth=? 深度(跨表查询,可控性查,效率低)

 

ModelSerializer
            -必须在类中写
            class Meta:
                model=指定表
                # fields = '__all__'
                # 指定只取这两个字段
                fields = ['nid','name']
                # 去掉指定的字段
                # exclude=['publish','authors']
                # fields,跟exclude不能连用
                # 指定深度,就是跨几个表(官方建议小于10,我给你的建议小于3)
                # depth = 2
原文地址:https://www.cnblogs.com/ouyang99-/p/10104906.html