zoukankan      html  css  js  c++  java
  • django rest-framework 3.类 实现restful

    上节提到过,REST框架分别提供了对函数和类的装饰器,之前已经都是通过函数来写视图函数的,现在来尝试使用class 类来实现视图函数

    使用基于类编写API视图,允许重用常用的功能,减少代码重复。

    一、REST框架基于类实现API

    根据之前的函数视图重写基于类的视图,只涉及到了重构views.py

    # 第三种 类视图
    from django.http import Http404
    from test_app import serializer
    from test_app import models
    from rest_framework import views    # views.APIView 为类的装饰器
    from rest_framework.response import Response
    from rest_framework import status    
    
    
    class Game_List(views.APIView):
        def get(self, request, format=None):
            games_obj = models.Game.objects.all()
            games_serializer = serializer.Test_app_model_serializer(instance=games_obj, many=True)
            return Response(games_serializer.data, status=status.HTTP_200_OK)
    
        def post(self, reqeust, format=None):
            data = reqeust.data
            game_serializer = serializer.Test_app_model_serializer(data=data)
            if game_serializer.is_valid():
                game_serializer.save()
                return Response(game_serializer.data, status=status.HTTP_201_CREATED)
            return Response(game_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    

    现在看起来和之前类似,但在不同的HTTP方式之间有更好的分离,继续编写更新实例视图

    class Game_Info(views.APIView):
        def get_obj(self, game_id):
            try:
                return models.Game.objects.get(id=game_id)
            except models.Game.DoesNotExist as not_exist:
                raise Http404
    
        def get(self, reqeust, game_id, format=None):   # 函数视图和类函数都可以使用路由系统传递过来的未命名分组数据
            game_serializer = serializer.Test_app_model_serializer(instance=self.get_obj(game_id))
            return Response(game_serializer.data)
    
        def put(self, request, game_id, format=None):
            game_serializer = serializer.Test_app_model_serializer(instance=self.get_obj(game_id), data=request.data)
            if game_serializer.is_valid():
                game_serializer.save()
                return Response(game_serializer.data)
            return Response(game_serializer.errors)
    
        def delete(self, request, game_id, format=None):
            self.get_obj(game_id).delete()
            return Response(status.HTTP_204_NO_CONTENT)

     二、使用mixins类实现视图函数

    下面来使用REST框架的mixins类中实现

    # 第四种 mixin类视图
    from test_app import serializer
    from test_app import models
    from rest_framework import mixins
    from rest_framework import generics
    
    
    class Game_List(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
        queryset = models.Game.objects.all()
        serializer_class = serializer.Test_app_model_serializer
    
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)

    基类提供核心功能,而mixin类提供.list().create()操作。然后,我们将明确的绑定getpost方法绑定到适当的操作。到目前为止足够简单的东西

    class Game_Info(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
        queryset = models.Game.objects.all()
        serializer_class = serializer.Test_app_model_serializer
    
        def get(self, request, *args, **kwargs):
            print(request,args,kwargs)
            return self.retrieve(request, *args, **kwargs)
    
        def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
    
        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    

    同样,我们正在使用的GenericAPIView类来提供核心功能,并混入增加提供.retrieve().update().destroy()方法。

    三、使用泛型类视图

    # 第五种 泛型类视图
    from test_app import serializer
    from test_app import models
    from rest_framework import generics
    
    
    class Game_List(generics.ListCreateAPIView):
        queryset = models.Game.objects.all()
        serializer_class = serializer.Test_app_model_serializer
    
    
    class Game_Info(generics.RetrieveUpdateDestroyAPIView):
        queryset = models.Game.objects.all()
        serializer_class = serializer.Test_app_model_serializer

    汇总:

    from django.shortcuts import render
    from django.http import HttpResponse, JsonResponse
    from django.views.decorators.csrf import csrf_exempt  # 忽略post请求时的csrf问题
    from test_app import serializer
    from test_app import models
    from rest_framework.renderers import JSONRenderer  # restful提供的序列化类
    from rest_framework.parsers import JSONParser  # restful提供的反序列化类
    
    # Create your views here.
    
    # # 第一种函数视图
    # @csrf_exempt
    # def game_list(request):
    #     if request.method == 'GET':
    #         print(request.data)
    #         game = models.Game.objects.all()  # 获取数据库中所有数据
    #         game_serializer = serializer.Test_app_model_serializer(instance=game,
    #                                                          many=True)  # 通过自定义的serializer实例化数据,many参数为True表示处理多条数据
    #         # return HttpResponse(JSONRenderer().render(game_serializer.data), status=200)  # 序列化serializer实例的数据
    #         return JsonResponse(game_serializer.data,safe=False)
    #     elif request.method == 'POST':
    #         data = JSONParser().parse(request)  # 通过JsonParser类反序列化POST过来的数据
    #         game_serializer = serializer.Test_app_model_serializer(data=data)  # 通过反序列化后的数据创建serializer实例
    #         print(game_serializer)
    #         if game_serializer.is_valid():  # 通过is_valid()方法判断数据类型是否正确,这点和Django的From相似
    #             game_serializer.save()  # 验证通过保存数据,这里的game_serializer是自定义serializer的create函数返回的对象,进行保存
    #             # return HttpResponse(JSONRenderer().render(game_serializer.data))  # 序列化数据返回前端
    #             return JsonResponse(game_serializer.data,safe=False)
    #         else:  # 验证不通过,输出对应的报错信息
    #             print("验证不通过")
    #             # return HttpResponse(JSONRenderer().render(game_serializer.errors))
    #             print(type(game_serializer.errors))
    #             return JsonResponse(game_serializer.errors)
    #
    # # 注释同上
    # @csrf_exempt
    # def game_info(request, game_id):
    #     game_obj = models.Game.objects.get(id=game_id)
    #     if request.method == 'GET':
    #         game_serializer = serializer.Test_app_model_serializer(instance=game_obj)
    #         data = JSONRenderer().render(game_serializer.data)
    #         return HttpResponse(data)
    #     elif request.method == 'PUT':
    #         data = JSONParser().parse(request)
    #         game_serializer = serializer.Test_app_model_serializer(instance=game_obj, data=data)
    #         if game_serializer.is_valid():
    #             game_serializer.save()
    #             # return HttpResponse(JSONRenderer().render(game_serializer.data))
    #             return JsonResponse(game_serializer.data, status=201)
    #         return JsonResponse(game_serializer.errors, status=400)
    #     elif request.method == 'DELETE':
    #         game_obj.delete()
    #         return HttpResponse(status=204)
    
    
    # 第二种函数视图
    # from rest_framework import status
    # from rest_framework.decorators import api_view
    # from rest_framework.response import Response
    # from test_app import serializer
    # from test_app import models
    #
    #
    # @api_view(['GET', 'POST'])
    # def game_list(request, format=None):
    #     print(format)
    #     if request.method == 'GET':
    #         games = models.Game.objects.all()
    #         games_serializer = serializer.Test_app_model_serializer(instance=games, many=True)
    #         return Response(games_serializer.data)
    #     elif request.method == 'POST':
    #         game_serializer = serializer.Test_app_model_serializer(data=request.data)
    #         if game_serializer.is_valid():
    #             game_serializer.save()
    #             return Response(game_serializer.data, status=status.HTTP_201_CREATED)
    #         return Response(game_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #
    #
    # @api_view(['GET', 'PUT', 'DELETE'])
    # def game_info(request, game_id, format=None):
    #     try:
    #         game_obj = models.Game.objects.get(id=game_id)
    #     except models.Game.DoesNotExist as e:
    #         return Response(status=status.HTTP_404_NOT_FOUND)
    #         # return HttpResponse(e,status=status.HTTP_404_NOT_FOUND)
    #     if request.method == 'GET':
    #         game_serializer = serializer.Test_app_model_serializer(instance=game_obj)
    #         return Response(game_serializer.data)
    #     elif request.method == 'PUT':
    #         game_serializer = serializer.Test_app_model_serializer(instance=game_obj, data=request.data)
    #         if game_serializer.is_valid():
    #             game_serializer.save()
    #             return Response(game_serializer.data)
    #         return Response(game_serializer.errors)
    #     elif request.method == 'DELETE':
    #         game_obj.delete()
    #         return Response(status=status.HTTP_204_NO_CONTENT)
    
    
    # # 第三种 APIView类视图
    # from django.http import Http404
    # from test_app import serializer
    # from test_app import models
    # from rest_framework import views
    # from rest_framework.response import Response
    # from rest_framework import status
    #
    #
    # class Game_List(views.APIView):
    #     def get(self, request, format=None):
    #         print(locals())
    #         games_obj = models.Game.objects.all()
    #         games_serializer = serializer.Test_app_model_serializer(instance=games_obj, many=True)
    #         return Response(games_serializer.data, status=status.HTTP_200_OK)
    #
    #     def post(self, reqeust, format=None):
    #         data = reqeust.data
    #         game_serializer = serializer.Test_app_model_serializer(data=data)
    #         if game_serializer.is_valid():
    #             game_serializer.save()
    #             return Response(game_serializer.data, status=status.HTTP_201_CREATED)
    #         return Response(game_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #
    #
    # class Game_Info(views.APIView):
    #     def get_obj(self, game_id):
    #         try:
    #             return models.Game.objects.get(id=game_id)
    #         except models.Game.DoesNotExist as not_exist:
    #             raise Http404
    #
    #     def get(self, reqeust, game_id,format=None):
    #         game_serializer = serializer.Test_app_model_serializer(instance=self.get_obj(game_id))
    #         return Response(game_serializer.data)
    #
    #     def put(self, request, game_id, format=None):
    #         game_serializer = serializer.Test_app_model_serializer(instance=self.get_obj(game_id), data=request.data)
    #         if game_serializer.is_valid():
    #             game_serializer.save()
    #             return Response(game_serializer.data)
    #         return Response(game_serializer.errors)
    #
    #     def delete(self, request, game_id, format=None):
    #         self.get_obj(game_id).delete()
    #         return Response(status.HTTP_204_NO_CONTENT)
    
    
    # # 第四种 mixin类视图
    # from test_app import serializer
    # from test_app import models
    # from rest_framework import mixins
    # from rest_framework import generics
    #
    #
    # class Game_List(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    #     queryset = models.Game.objects.all()
    #     serializer_class = serializer.Test_app_model_serializer
    #
    #     def get(self, request, *args, **kwargs):
    #         return self.list(request, *args, **kwargs)
    #
    #     def post(self, request, *args, **kwargs):
    #         return self.create(request, *args, **kwargs)
    #
    #
    # class Game_Info(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
    #     queryset = models.Game.objects.all()
    #     serializer_class = serializer.Test_app_model_serializer
    #
    #     def get(self, request, *args, **kwargs):
    #         print(request,args,kwargs)
    #         return self.retrieve(request, *args, **kwargs)
    #
    #     def put(self, request, *args, **kwargs):
    #         return self.update(request, *args, **kwargs)
    #
    #     def delete(self, request, *args, **kwargs):
    #         return self.destroy(request, *args, **kwargs)
    
    
    
    # 第五种 泛型类视图
    from test_app import serializer
    from test_app import models
    from rest_framework import generics
    
    
    class Game_List(generics.ListCreateAPIView):
        queryset = models.Game.objects.all()
        serializer_class = serializer.Test_app_model_serializer
    
    
    class Game_Info(generics.RetrieveUpdateDestroyAPIView):
        queryset = models.Game.objects.all()
        serializer_class = serializer.Test_app_model_serializer
    REST视图函数的实现方法
  • 相关阅读:
    云路五年 未来正来
    免费公测:RDS只读实例
    【Open Search产品评测】-- 淘点点:基于OpenSearch,轻松实现一整套O2O类搜索解决方案
    阿里云启动“云合计划” 培育中国“微软”级企业
    【Open Search产品评测】- 来往,7天轻松定制属于自己的搜索引擎
    水塘抽样算法
    如何调度考生的座位
    如何去除有序数组的重复元素
    二分查找高效判定子序列
    如何k个一组反转链表
  • 原文地址:https://www.cnblogs.com/40kuai/p/7599480.html
Copyright © 2011-2022 走看看