DRF Serializers 序列化

序列化和反序列化

序列化,是指将复杂的QuerySet和Model类型转换成Python基本数据类型,从而将这些基本数据类型以JSON的形式响应给客户端。

反序列化则和序列化相反,是指将Http请求中传入的JSON数据转换成复杂的数据类型,从而保存在数据库中。

在REST Framework中,提供了多个用于序列化操作的类,但常用的也就如下两个:

Serializer:进行序列化基本的类;
ModelSerializer:继承于Serializer,内部实现了通用的序列化逻辑,其中包含了与Model字段对应的字段,可以快速对Model进行序列化。
使用时需要导入对应模块:

from rest_framework import serializers

Serializers 序列化组件

  • Serializer 组件
  • ModelSerializer组件
  • HyperlinkedIdentityField组件 - 用于链接的拼接
serializer
from rest_framework.views import APIView
from rest_framework.serializers import Serializer
from rest_framework import serializers
 
 
# 写一个与modles内表类对应的Serializer类,用于获取需求序列化的字段
# 字段必须在modles对应表内进行定义
class BookSerializer(Serializer):
    name = serializers.CharField()
    # price=serializers.CharField()
    # date=serializers.CharField()
 
 
class Books(APIView):
 
    def get(self, request):
 
        # 序列化多个对象(many=True)
        books = models.Book.objects.all()
        # instance=books要序列化的queryset对象,many=True,表示序列化多条
        ser = BookSerializer(instance=books, many=True)
        print(ser.data)
        # [OrderedDict([('name', 'name')]), OrderedDict([('name', '水')]), OrderedDict([('name', '水都是')])]
 
        # instance:可以不写,按位置传 - instance位于位置传参的第一位
        # ser=BookSerializer(books,many=True)
 
        # 序列化单个对象 many=False
        book = models.Book.objects.all().first()
        ser=BookSerializer(book,many=False)
 
        # ser.data 拿到的是序列化之后的字典,字典里可能套了列表,所以safe=False
        return JsonResponse(ser.data, safe=False)
ModelSerializer
  • ModelSerializer组件必须配合Meta使用,对指定的字段进行序列化处理和返回
  • Meta内注意事项:
    • model需导入models内对应处理表类
    • fields - 用于获取需处理的表内字段
    • fields=‘all’ - 获取所有字段进行序列化处理;后续可用常规方式重写属性,覆盖all序列的操作
    • fields = [‘nid’,‘name’] - 获取指定字段进行序列化处理并返回
    • exclude=[‘publish’,‘authors’] - 用于去除字段,不序列化并且不返回
    • depth = 2 - 关系表的深度指定(不建议使用,对数据库的频繁操作降低效率)
from ap01.models import Book
from rest_framework import serializers

class AuthorSerializer(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()
    
class BookSerializer(serializers.ModelSerializer):
    # 必须写一个Meta内部类
    class Meta:
        # 序列化的对象,models内的对应表类
        # 需导入from ap01.models import Book
        model = Book
        # 对表内所有字段进行序列化处理
        fields = '__all__'
        # 指定只取这两个字段
        # fields = ['nid','name']
        # 去掉指定的字段,选入字段不进行序列化且不返回
        # exclude=['publish','authors']
        # fields,跟exclude不能连用
        # 指定深度(官方建议小于10,我给你的建议小于3),和关联表的深度 - 不建议使用
        # depth = 2
 
    # 重写属性,覆盖Meta内初始化操作
    publish = serializers.CharField(source='publish.name')
    authors = serializers.SerializerMethodField()
 
    def get_authors(self, book):
        # 拿到这本书的所有作者
        aus = book.authors.all()
        # 可以继续用序列化类,来处理
        auth_ser = AuthorSerializer(aus, many=True)
        return auth_ser.data
HyperlinkedIdentityField - 用于链接的拼接
'''
mySer.py
  HyperlinkedIdentityField 必传参数:
    - view_name:urls.py路由文件内反向解析名
    - lookup_field:models内对应路由传入的参数
    - lookup_url_kwarg:urls.py路由文件内对应有名参数名
        - 注意:可以传入跨表字段,必须是联系表
            例如:假设publish表类内存在外联关系表book - 'book_id'
'''
class PublishSerializer(serializers.Serializer):
    name = serializers.CharField()
    city = serializers.CharField()
    publish_url = serializers.HyperlinkedIdentityField(view_name='urls_publish',lookup_field='nid',lookup_url_kwarg='id')
 
'''
urls.py
'''
url(r'^publish/(?P<id>\d+)', views.Publish.as_view(),name='urls_publish'),
 
'''
views.py
   PublishSerializer 必传参数:
    - instance:序列化对象
    - mangy:序列化对象的单复数
    - context:获取链接中的域名,即 http://127.0.0.1:8000
'''
class Publish(APIView):
    def get(self, request, *args, **kwargs):
        ret = models.Publish.objects.all()
        publish_ser = PublishSerializer(ret, many=True,context={'request': request})
        return JsonResponse(publish_ser.data, safe=False)

参考

https://blog.csdn.net/qq_33961117/article/details/84955113

serializers 详解

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值