首页 > 其他分享 >django-rest-framework-从零开始-8-Serializer多序列化一个字段

django-rest-framework-从零开始-8-Serializer多序列化一个字段

时间:2023-03-21 19:02:58浏览次数:77  
标签:get self queryset rest django game 序列化 id serializer

django-rest-framework-从零开始-8-Serializer多序列化一个字段

1、前言

这里是属于自己的项目需求,而研究的功能。

  • 目的:想在Serializer类中,多显示一个字段。

例如:模型使用之前的Student模型

image-20230317160104729

  • 情景:学校里面举办了一个游戏,游戏中,每个同学有一个自己的唯一的游戏ID,我们可以使用学号作为游戏ID,但为了演示新功能,我们不用学号,而是通过UUID为每个学生来生成一个游戏ID。
  • 真实场景是,数据库中记录了虚拟机的信息,但是没记录IP,毕竟IP会变,每次调用时,通过其他http接口,获取到IP,然后显示

想到达到的效果是,通过get请求,获取所有学生信息时,多显示一个额外的字段,称为game_id。

原来通过获取的返回数据和我们想显示的数据如下

image-20230317161521420

2、在Serializer类中多序列化一个字段

在此之前,我们知道了怎么快速创建一个CRUD的drf项目,而且知道发送get请求,最终会调用视图的list方法,因此改造步骤如下:

(1)序列化类中添加想要显示的字段

修改student_manager/serializers.py文件中的StudentSerializer

class StudentSerializer(serializers.ModelSerializer):
    game_id = serializers.CharField(read_only=True)

    class Meta:
        model = Student
        fields = '__all__'

说明:添加了一个game_id的字段,且设置为read_only,设置完read_only才会跳过从数据库同步,因此模型类没有该属性,想通过数据库同步,必然是失败的,不加read_only=True会这样报错

AttributeError: Got AttributeError when attempting to get a value for field game_id on serializer StudentSerializer.

image-20230317162405159

很好理解,就是去获取字段时,通过getattr获取,获取不到,则报错,因此设置为read_only=True即可

(2)重写视图函数中的list函数

因为最终调用是走的list函数,因此重写list函数即可,文件是student_manager/views.py

class StudentList(generics.ListCreateAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        for one in serializer.data:
            one['game_id'] = uuid.uuid4().hex
        return Response(serializer.data)

我们在获取到serializer.data时,添加game_id属性即可

(3)Detail的get对应retrieve方法也需要重写一下

class StudentDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        data = serializer.data
        data['game_id'] = uuid.uuid4().hex
        return Response(data)

当然,如果post、put时,也想显示game_id,则需要重新对应的方法

(4)验证

发送List视图的get请求,验证数据

image-20230317163618478

发送Detail视图的get请求

image-20230317164408598

github:https://github.com/rainbow-tan/learn-drf

标签:get,self,queryset,rest,django,game,序列化,id,serializer
From: https://www.cnblogs.com/rainbow-tan/p/17241043.html

相关文章

  • django-rest-framework-从零开始-6-视图类GenericAPIView的使用
    django-rest-framework-从零开始-6-视图类GenericAPIView的使用1、前言之前提到过的基于APIView类的视图,需要重写["get","post","put","patch","delete","head","opti......
  • django-rest-framework-从零开始-3-序列化类ModelSerializer的使用
    django-rest-framework-从零开始-3-序列化类ModelSerializer的使用1、前言我们之前提到创建序列化类,需要继承serializers.Serializer类,然后映射模型类的字段,然后重写crea......
  • django-rest-framework-从零开始-2-序列化类serializers.Serializer的使用
    django-rest-framework-从零开始-2-序列化类serializers.Serializer的使用1、前言我们编写的django程序,需要与前端或者其他程序交互,通常会提供出自己的API接口,此时需要把......
  • Python Django 加法计算器案例
    创建add应用在templates内新建add.html文件:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Co......
  • Python Django 登陆案例
    在根目录下新建一个templates文件将该目录添加到settings.py文件内在templates文件夹内新建一个login.html文件,并写入模板内容<!DOCTYPEhtml><htmllang="z......
  • JAVA -适合新手和复习(Restart)
    作为22届专科生,在没有经历和学历的情况下找一份得体的工作 是多么“奢侈”,世上岂无千里马,人中难得九方皋.废话太多我们开始吧!JAVA从这里开始 Java的历史(不感兴趣直......
  • django中使用分页器功能
    要使用Django实现分页器,必须从Django中导入Paginator模块fromdjango.core.paginatorimportPaginator假如现在有150条记录要显示,每页显示10条>>>fromdjango.co......
  • 如何自动化测试你的接口?—— Rest Assured
    前言不知道大家的项目是否都有对接口API进行自动化测试,反正像我们这种小公司是没有的。由于最近一直被吐槽项目质量糟糕,只能研发自己看看有什么接口测试方案。那么在本文......
  • Forest与Sa-token
    Forest简介什么是Forest?Forest是一个开源的JavaHTTP客户端框架,它能够将HTTP的所有请求信息(包括URL、Header以及Body等信息)绑定到您自定义的Interface方法......
  • FastJson序列化后Date日期类型变成时间戳
    日志执行结果:以上可以看到productionDate通过FastJson序列化后变成时间戳了解决方式一:日期属性字段上添加@JSONField注解@JSONField(format="yyyy-MM-dd")priva......