django rest-framework 3.類 實現restful

上節提到過,REST框架分別提供了對函數和類的裝飾器,以前已經都是經過函數來寫視圖函數的,如今來嘗試使用class 類來實現視圖函數前端

使用基於類編寫API視圖,容許重用經常使用的功能,減小代碼重複。python

1、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方式之間有更好的分離,繼續編寫更新實例視圖django

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)

 2、使用mixins類實現視圖函數

下面來使用REST框架的mixins類中實現api

# 第四種 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方法綁定到適當的操做。到目前爲止足夠簡單的東西restful

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()方法。app

3、使用泛型類視圖框架

# 第五種 泛型類視圖
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

彙總:ide

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視圖函數的實現方法
相關文章
相關標籤/搜索