zoukankan      html  css  js  c++  java
  • rest_framework序列化组件

    一、Django自带的序列化组件  ==》对象序列化成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部分

     1 from django.db import models
     2 
     3 # Create your models here.
     4 
     5 
     6 class Book(models.Model):
     7     title=models.CharField(max_length=32)
     8     price=models.IntegerField()
     9     pub_date=models.DateField()
    10     publish=models.ForeignKey("Publish")
    11     authors=models.ManyToManyField("Author")
    12     def __str__(self):
    13         return self.title
    14 
    15 class Publish(models.Model):
    16     name=models.CharField(max_length=32)
    17     email=models.EmailField()
    18     def __str__(self):
    19         return self.name
    20 
    21 class Author(models.Model):
    22     name=models.CharField(max_length=32)
    23     age=models.IntegerField()
    24     def __str__(self):
    25         return self.name
    View Code

    views部分

     1 from rest_framework.views import APIView
     2 from rest_framework.response import Response
     3 from .models import *
     4 from django.shortcuts import HttpResponse
     5 from django.core import serializers
     6 
     7 
     8 from rest_framework import serializers
     9 
    10 class BookSerializers(serializers.Serializer):  ===》这里的Serializer是大写开头
    11     title=serializers.CharField(max_length=32)
    12     price=serializers.IntegerField()
    13     pub_date=serializers.DateField()
    14     publish=serializers.CharField(source="publish.name")
    15     #authors=serializers.CharField(source="authors.all")
    16     authors=serializers.SerializerMethodField()  ==》这里用这个下面需要跟上get + 字段
    17     def get_authors(self,obj):
    18         temp=[]
    19         for author in obj.authors.all():
    20             temp.append(author.name)
    21         return temp
    22   #此处可以继续用author的Serializers,
    23   # def get_authors(self,obj):
    24     #     ret=obj.authors.all()
    25     #     ss=AuthorSerializer(ret,many=True)
    26     #     return ss.data
    27 
    28 class BookViewSet(APIView):
    29 
    30     def get(self,request,*args,**kwargs):
    31         book_list=Book.objects.all()
    32         # 序列化方式1:
    33         # from django.forms.models import model_to_dict
    34         # import json
    35         # data=[]
    36         # for obj in book_list:
    37         #     data.append(model_to_dict(obj))
    38         # print(data)
    39         # return HttpResponse("ok")
    40 
    41         # 序列化方式2:
    42         # data=serializers.serialize("json",book_list)
    43         # return HttpResponse(data)
    44 
    45         # 序列化方式3:
    46         bs=BookSerializers(book_list,many=True)     #many=True代表有多条数据,如果只有一条数据,many=False
    47         return Response(bs.data)
    48      # 序列化方式4: 
    49       # ret=models.Book.objects.all().values('nid','title')
    50      # dd=list(ret)
    51         # return HttpResponse(json.dumps(dd))

    注意:

    source 如果是字段,会显示字段,如果是方法,会执行方法,不用加括号(authors=serializers.CharField(source='authors.all'))

    如在模型中定义一个方法,直接可以在在source指定执行

    二、rest_framework序列化之ModelSerializer

     1 class BookSerializers(serializers.ModelSerializer):
     2     class Meta:
     3         model = models.Book
     4         # fields = "__all__"
     5         fields=['nid','title','authors','publish']
     6         # exclude=('nid',)   #不能跟fields同时用
     7         # depth = 1    #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层
     8     publish=serializers.SerializerMethodField()
     9     def get_publish(self,obj):
    10         return obj.publish.name
    11     authors=serializers.SerializerMethodField()
    12     def get_authors(self,obj):
    13         ret=obj.authors.all()
    14         ss=AuthorSerializer(ret,many=True)
    15         return ss.data

    三、序列化组件之请求数据校验和保存功能

     1 class BookSerializers(serializers.ModelSerializer):
     2     class Meta:
     3         model=Book
     4         fields="__all__"
     5 
     6 #————————
     7 class BookView(APIView):
     8 
     9     def post(self, request):
    10 
    11         # 添加一条数据
    12         print(request.data)
    13 
    14         bs=BookSerializers(data=request.data)
    15         if bs.is_valid():
    16             bs.save()  # 生成记录
    17             return Response(bs.data)
    18         else:
    19 
    20             return Response(bs.errors)

    通过源码查看留的校验字段的钩子函数:

     1 #is_valid---->self.run_validation-(执行Serializer的run_validation)-->self.to_internal_value(data)---(执行Serializer的run_validation:485行)
     2 def validate_title(self, value):
     3         from rest_framework import exceptions
     4         raise exceptions.ValidationError('看你不顺眼')
     5         return value
     6 
     7 #全局
     8 def validate(self, attrs):
     9     from rest_framework import exceptions
    10     if attrs.get('title')== attrs.get('title2'):
    11         return attrs
    12     else:
    13         raise exceptions.ValidationError('不想等啊')

    序列化组件源码分析

    序列化组件,先调用__new__方法,如果many=True,生成ListSerializer对象,如果为False,生成Serializer对象
    序列化对象.data方法--调用父类data方法---调用对象自己的to_representation(自定义的序列化类无此方法,去父类找)
    Aerializer类里有to_representation方法,for循环执行attribute = field.get_attribute(instance)
    再去Field类里去找get_attribute方法,self.source_attrs就是被切分的source,然后执行get_attribute方法,source_attrs
    当参数传过去,判断是方法就加括号执行,是属性就把值取出来


  • 相关阅读:
    有用的文件(配置文件)
    gulp webpack 区别
    vue ssr
    微信小程序自定义组件
    mpvue 搭建小程序
    【转】DotNet加密方式解析--非对称加密
    java RSA加密算法
    【转】C#中RSA加密解密和签名与验证的实现
    C# 字符串 分割 反转 Base64
    RSA加密算法
  • 原文地址:https://www.cnblogs.com/Roc-Atlantis/p/9794762.html
Copyright © 2011-2022 走看看