• 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
  • 相关阅读:
    金蝶K3 账套复制
    silverlight控件如何自适应
    一个使用Jquery写的一个鼠标拖动效果
    如何使用C#开发“类ActiveX组件”
    一个非科班出身程序员的成长历程
    Ubuntu 12.04下LAMP安装配置
    Abp vue项目找不到模块“./app.vue”
    google的分析(analytics)js代码分析以及重写
    javascript实现类似google和msn space的拖拽
    Lucene.Net, SQL Server 2008全文检索, Like模糊查询的一点心得
  • 原文地址:https://www.cnblogs.com/ouyang99-/p/10104906.html
Copyright © 2020-2023  润新知