DRF框架中的演变View
import json from django.db import DatabaseError from django.http import HttpResponse from django.http import JsonResponse from django.shortcuts import render
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# Create your views here. from django.views import View # http://127.0.0.1:8000/books/ from rest_framework.authentication import SessionAuthentication from rest_framework.decorators import action from rest_framework.generics import GenericAPIView, CreateAPIView, ListAPIView, RetrieveAPIView, UpdateAPIView,DestroyAPIView, ListCreateAPIView, RetrieveUpdateDestroyAPIView from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin,DestroyModelMixin from rest_framework.pagination import PageNumberPagination from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.response import Response from rest_framework.throttling import UserRateThrottle from rest_framework.views import APIView from rest_framework.viewsets import ModelViewSet from books.models import BookInfo, HeroInfo from books.serializers import BookInfoSerializer, HeroInfoSerializer, BookInfoModelSerializer, HeroInfoModelSerializer,BookInfoSerializerForModidyRead
def test(request): s = HeroInfoModelSerializer() print(s) return HttpResponse("OK") print("使用view开始")
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# http://127.0.0.1:8000/heros/id/ class HeroView(View): def get(self,request,pk): try: hero = HeroInfo.objects.get(pk=pk) except Exception as e: return HttpResponse(status=404) serializer = HeroInfoSerializer(hero) return JsonResponse(serializer.data) class BooksView(View): def get(self, request): try: books = BookInfo.objects.all() except Exception as e: return HttpResponse(status=404) serializer = BookInfoSerializer(books,many=True) return JsonResponse(serializer.data,safe=False) def post(self, request): json_bytes = request.body json_str = json_bytes.decode() json_dict = json.loads(json_str) print(json_dict) # 校验参数 serializer = BookInfoSerializer(data=json_dict) # 如果校验不成功直接抛出异常 success = serializer.is_valid(raise_exception=True) print(success) if success: serializer.save() return JsonResponse(serializer.data,status=201) # http://127.0.0.1:8000/books/id/ class BookView(View): def get(self, request, pk): try: book = BookInfo.objects.get(pk=pk) except Exception as e: return HttpResponse(status=404) serializer = BookInfoSerializer(book) return JsonResponse(serializer.data) def put(self, request, pk): try: book = BookInfo.objects.get(pk=pk) except Exception as e: return HttpResponse(status=404) json_bytes = request.body json_str = json_bytes.decode() json_dict = json.loads(json_str) print(json_dict) serializer = BookInfoSerializer(instance=book, data=json_dict,partial=True) # 如果校验不成功直接抛出异常 success = serializer.is_valid(raise_exception=True) print(success) if success: serializer.save() return JsonResponse(serializer.data,status=201) def delete(self, request, pk): try: book = BookInfo.objects.get(pk=pk) except Exception as e: return HttpResponse(status=404) book.delete() return HttpResponse(status=204)
print("使用View结束") print("使用APIView开始") # 利用APIView中强大的request和response # request中的request.data可以自动帮我们进行解码操作,因为其中含有DRF的Parser解析器,会自动的根据 # content-type解析数据,将解析的数据添加到Request类中, # response可以根据我们的请求给我们返回我们需要的数据,用户想要什么界面就可以直接渲染出想要的结果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class BooksView(APIView): def get(self, request): books = BookInfo.objects.all() serializer = BookInfoModelSerializer(books,many=True) return Response(serializer.data) def post(self, request): # 校验参数 serializer = BookInfoModelSerializer(data=request.data) # 如果校验不成功直接抛出异常 success = serializer.is_valid(raise_exception=True) if success: serializer.save() return Response(serializer.validated_data,status=201) # http://127.0.0.1:8000/books/id/ class BookView(APIView): def get(self, request, pk): book = BookInfo.objects.get(pk=pk) serializer = BookInfoModelSerializer(book) return Response(serializer.data) def put(self, request, pk): book = BookInfo.objects.get(pk=pk) serializer = BookInfoModelSerializer(instance=book, data=request.data,partial=True) # 如果校验不成功直接抛出异常 success = serializer.is_valid(raise_exception=True) if success: serializer.save() return Response(serializer.validated_data,status=201) def delete(self, request, pk): book = BookInfo.objects.get(pk=pk) book.delete() return HttpResponse(status=204)
print("使用APIView结束") print("使用GenericAPIView开始")
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class BooksView(GenericAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoModelSerializer def get(self, request): books = self.get_queryset() serializer = self.get_serializer(books,many=True) return Response(serializer.data) def post(self, request): # 校验参数 serializer = self.get_serializer(data=request.data) # 如果校验不成功直接抛出异常 print(request.data) success = serializer.is_valid(raise_exception=True) print(success) if success: serializer.save() return Response(serializer.validated_data,status=201) # http://127.0.0.1:8000/books/id/ class BookView(GenericAPIView): queryset = BookInfo.objects.all() # serializer_class = BookInfoModelSerializer # lookup_url_kwarg 指定的是路径中参数的名称,默认叫pk # lookup_field 指的是数据库中的字段 # lookup_field = "id" def get_serializer_class(self): return BookInfoModelSerializer def get(self, request, pk): book = self.get_object() serializer = self.get_serializer(book) return Response(serializer.data) def put(self, request, pk): book = self.get_object() serializer = self.get_serializer(instance=book, data=request.data,partial=True) success = serializer.is_valid(raise_exception=True) if success: serializer.save() return Response(serializer.validated_data,status=201) def delete(self, request, pk): book = self.get_object() book.delete() return Response(status=204)
print("使用GenericAPIView以结束") print("GenericAPIView的扩展类开始") 扩展类:针对于某一个类进行功能的扩展,只能够结合这个类进行使用,不能单独使用 子类:针对父类的功能进行扩展,可以单独使用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class BooksView(ListModelMixin,CreateModelMixin,GenericAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoModelSerializer def get(self, request): return self.list(request) def post(self, request): return self.create(request) class BookView(RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoModelSerializer def get(self, request, pk): return self.retrieve(request,pk) def put(self, request, pk): return self.update(request,pk) def delete(self, request, pk): return self.destroy(request,pk)
print("GenericAPIView的扩展类以结束") # ListAPIView --> get() # CreateAPIView --> post() # ListCreateAPIView # get # post # RetrieveAPIView --> get() # UpdateAPIView --> put() patch() # DestroyAPIView --> delete() # RetrieveUpdateAPIView --> get() put() patch() # RetrieveDestroyAPIView --> get() delete() # RetrieveUpdateDestroyAPIView --> get() put() patch() delete()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class BooksView(ListCreateAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoModelSerializer class BookView(RetrieveUpdateDestroyAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoModelSerializer
print("GenericAPIView的子类以结束") print("使用视图集开始") # 关于图书的这个资源,我们不想写两个类视图,我们就想写一个类 # 关于图书的操作:获取列表\增加\获取单个\修改\删除 # list()\create()\retrieve()\update()\destory() # 视图集:视图集并不是必须的,如果你足够的懒,那么可以使用视图集 # 达到的效果:多个路径,只需要写一个class即可 # 注意:要在urls.py中来配置,不同路径\不同请求方法 究竟应该调用哪个方法 # 视图集的功能:可以让我们通过不同的路径,访问到同一个class中不同方法 # 视图集中自定义动作的实现: # 1\在urls.py中配置好路径和这个class中哪个方法的映射关系 # 2\在这个class中通过def的方式定义好方法, 这个方法中得要有request参数,可能会有pk
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# http://127.0.0.1:8000/books/?page=2&page_size=2/ class LargeResultsSetPagination(PageNumberPagination): page_size = 2 page_size_query_param = 'page_size' max_page_size = 10 class BookViewSet(ModelViewSet): """ list: 获取图书信息 retrieve: 获取 单个图书信息 latest: 获取图书的最新信息 read: 修改图书阅读量的数据 """ queryset = BookInfo.objects.all() # throttle_classes = (UserRateThrottle,) filter_fields = ('btitle', 'bread') pagination_class = LargeResultsSetPagination def get_permissions(self): if self.action == "latest": return [IsAuthenticated()] return [AllowAny()] # 我们可以通过视图集中的self.action决定当前是哪一种动作,通过不同的动作,返回不同的序列化器类的引用 def get_serializer_class(self): if self.action == "read": return BookInfoSerializerForModidyRead return BookInfoModelSerializer @action(methods=["get"],detail=False) def latest(self,request): raise DatabaseError() book = BookInfo.objects.latest("id") s = self.get_serializer(book) return Response(s.data) @action(methods=["put"],detail=True) def read(self,request,pk): book = self.get_object() s = self.get_serializer(book,data=request.data) success = s.is_valid(raise_exception=True) if success: s.save() return Response(s.validated_data,status=201)
print("使用视图集ViewSet结束") # 局部限流 class BookDetailView(RetrieveAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoModelSerializer authentication_classes = [SessionAuthentication] permission_classes = [IsAuthenticated] throttle_classes = (UserRateThrottle,) # 局部过滤 class BookListView(ListAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoModelSerializer filter_fields = ('btitle', 'bread')