上節提到過,REST框架分別提供了對函數和類的裝飾器,以前已經都是經過函數來寫視圖函數的,如今來嘗試使用class 類來實現視圖函數前端
使用基於類編寫API視圖,容許重用經常使用的功能,減小代碼重複。python
根據以前的函數視圖重寫基於類的視圖,只涉及到了重構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)
下面來使用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()
操做。而後,咱們將明確的綁定get
和post
方法綁定到適當的操做。到目前爲止足夠簡單的東西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