Django框架 --序列化组件(serializer)

一 、Django自带序列化组件

Django内置的serializers(把对象序列化成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部分(模型层):

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

view部分(视图层):

1、利用for循环来实现序列化(繁琐)

def get(self, request):
    response = {'status': 100, 'data': None}
    ll = [{'name': book.name, 'price': book.price} for book in books]
    # 返回数据是json格式数据
    response['data'] = ll
    # safe = True 表示数据可以是列表
    return JsonResponse(response, safe=False)

2、利用Django提供的序列化组件(不可控需要的字段)

Django内置的serializers

from django.core import serializers

def get(self,request):
    books = models.Book.objects.all()
    ret=serializers.serialize('json','queryset对象')
    #ret就是序列化之后的字符串了,不需要再序列化了
    return HttpResponse(ret)

3、利用drf提供的序列化组件

(1)基于Serializer类实现序列化——基本语法

-1 先导入
    from rest_framework.serializers import Serializer
    from rest_framework import serializers
-2 写一个类,继承Serializer
-3 在类内部写属性:
    name=serializers.CharField()
-4 使用:
    先生成对象,需要传参数 instance:要序列化的对象(可能是queryset,也可能是单个对象)    
    many:如果是queryset---True,,如果是单个对象--False
-5 序列化的数据:对象.data --->是一个字典
from rest_framework.views import APIView
from rest_framework import serializers


class BookSerializer(serializers.Serializer):
    name = serializers.CharField()


class Book(APIView):
    def get(self, request):
        # 要序列化的对象(可以是queryset,也可以是单个对象)
        # book = models.Books.objects.filter(name='红楼梦').first()
        # ser = BookSerializer(instance=book,many=False)
        books = models.Books.objects.all()
        ser = BookSerializer(instance=books, many=True)
        data = ser.data
        return JsonResponse(data, safe=False)

(2)基于Serializer类实现序列化——高级语法

<1>非关联字段或一对多字段

可以不用source,直接用 字段名 当变量名,必须为字段名

也可以用 source来指定需要的目标字段 (推荐,尽量让字段名不要泄露)

source也可以用来指定模型层中的方法

一对多关联关系,可以在 source 中用 .来指定字段,例如取出版社名字,用 source='publish.name'

from rest_framework.views import APIView
from rest_framework import serializers


class BookSerializer(serializers.Serializer):
    # 利用source来指定魔表字段,给key取别名
    aaa = serializers.CharField(source='name')  # 等价于 name = serializers.CharField()
    price = serializer.CharField()
    publish_name = serializer.CharField(source='publish.name')
    # source 也可以用来指定模型层中的方法
    t = serializer.CharField(source='publish.test')
    
    
class Book(APIView):
    def get(self, request):
        books = models.Books.objects.all()
        ser = BookSerializer(instance=books, many=True)
        data = ser.data
        return JsonResponse(data, safe=False)

<2>一对多或者多对多字段

多对多要用SerializerMethodField(),然后定义一个get_变量名的方法,方法名字必须为 

get_变量名get_变量名方法要传参,传入当前对象,例如在 BookSerializer 中就是book对象

get_变量名方法中,也可以对数据进行序列化,例如取书的所有作者,就可以对作者序列化然后 return

from rest_framework.views import APIView
from rest_framework import serializers

# 用于对author的数据进行序列化
class AuthorSerializer(serliazer.Serializer):
    name = serializer.CharField()
    age = serializer.CharField()


class BookSerializer(serializers.Serializer):
    # 利用source来给key取别名
    aaa = serializers.CharField(source='name')  # 等价于 name = serializers.CharField()
    price = serializer.CharField()
    
    # book和publish是一对多的关系,也可以用SerializerMethodField
    publish = serializer.SerializerMethodField()
    def get_publish(self, book):
       pub = book.publish.name
       return pub
    
    # book和authors是多对多的关系,用SerializerMethodField
    au = serializer.SerializerMethodField()
    def get_au(self, obj):
        aus = obj.authors.all()
        ll = []
        for obj_au in aus:
            ll.append({'au_name':obj_au.name,'au_age':obj_au.age})
        return ll
    
    # 也可以在方法中使用序列化类序列化
    '''
    def get_au(self, book):
        # 获取这本书的所有作者
        aus = book.authors.all()
        # 可以在方法中对authors的数据进行序列化
        au_ser = AuthorSerializer(aus,many=True)
        return au_ser.data
    '''

    
    
class Book(APIView):
    def get(self, request):
        books = models.Books.objects.all()
        ser = BookSerializer(instance=books, many=True)
        data = ser.data
        return JsonResponse(data, safe=False)

(3)基于ModelSerializer类实现序列化

<1>基本语法

from app01.models import Book

# 这样序列化得到的数据,authors是中都是author_id
class BookSerializer(serializer.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

<2>重写属性

from app01.models import Book

# 这样序列化得到的数据,authors中都是author_id,publish也是publish_id
class BookSerializer(serializer.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
    # 重写属性authors和publish
    puhlish = serializer.CharField(source='publish.name')
    authors = serializer.SerializerMethodField()
    def get_authors(self,book):
        aus = book.authors.all()
        # 可以在方法中对authors的数据进行序列化
        au_ser = AuthorSerializer(aus,many=True)
        return au_ser.data

<3>其他属性

fields = ['id','name'] ---------> 指定序列化这两个字段

exclude = ['publish','create_time'] ----------> 除了这两个字段外,其余的序列化

depth = 2 ----------> 指定深度,即跨表。值为1表示跨一次表;值为2表示跨两次表

class BookSerializer(serializers.ModelSerializer):
    # 必须写一个内部类,名字叫Meta
    class Meta:
        model = Book
        # fields = '__all__'
        # 指定只取这两个字段
        fields = ['nid','name']
        # 去掉指定的字段
        # exclude=['publish','authors']
        # fields,跟exclude不能连用
        # 指定深度(官方建议小于10,我给你的建议小于3)
        depth = 2

猜你喜欢

转载自www.cnblogs.com/zhangbingsheng/p/10106431.html