二:视图使用进化

初识rest_framework,视图使用时,类继承APIview,每个类相似的冗余代码过多:

from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
from django.shortcuts import HttpResponse
from django.core import serializers


from rest_framework import serializers


class BookSerializers(serializers.ModelSerializer):
      class Meta:
          model=Book
          fields="__all__"
          #depth=1


class PublshSerializers(serializers.ModelSerializer):

      class Meta:
          model=Publish
          fields="__all__"
          depth=1


class BookViewSet(APIView):

    def get(self,request,*args,**kwargs):
        book_list=Book.objects.all()
        bs=BookSerializers(book_list,many=True,context={'request': request})
        return Response(bs.data)


    def post(self,request,*args,**kwargs):
        print(request.data)
        bs=BookSerializers(data=request.data,many=False)
        if bs.is_valid():
            print(bs.validated_data)
            bs.save()
            return Response(bs.data)
        else:
            return HttpResponse(bs.errors)


class BookDetailViewSet(APIView):

    def get(self,request,pk):
        book_obj=Book.objects.filter(pk=pk).first()
        bs=BookSerializers(book_obj,context={'request': request})
        return Response(bs.data)

    def put(self,request,pk):
        book_obj=Book.objects.filter(pk=pk).first()
        bs=BookSerializers(book_obj,data=request.data,context={'request': request})
        if bs.is_valid():
            bs.save()
            return Response(bs.data)
        else:
            return HttpResponse(bs.errors)


class PublishViewSet(APIView):

    def get(self,request,*args,**kwargs):
        publish_list=Publish.objects.all()
        bs=PublshSerializers(publish_list,many=True,context={'request': request})
        return Response(bs.data)


    def post(self,request,*args,**kwargs):

        bs=PublshSerializers(data=request.data,many=False)
        if bs.is_valid():
            # print(bs.validated_data)
            bs.save()
            return Response(bs.data)
        else:
            return HttpResponse(bs.errors)


class PublishDetailViewSet(APIView):

    def get(self,request,pk):

        publish_obj=Publish.objects.filter(pk=pk).first()
        bs=PublshSerializers(publish_obj,context={'request': request})
        return Response(bs.data)

    def put(self,request,pk):
        publish_obj=Publish.objects.filter(pk=pk).first()
        bs=PublshSerializers(publish_obj,data=request.data,context={'request': request})
        if bs.is_valid():
            bs.save()
            return Response(bs.data)
        else:
            return HttpResponse(bs.errors)
    path('book/', views.BookView.as_view()),
    re_path('^book/(d+)', views.BookDetailView.as_view()),

rest_framework提供mixins类,让我们的代码变得简洁起来:

from rest_framework import serializers
from app01 import models

class BookSerializers(serializers.ModelSerializer):
    # authors = AuthorsSerializers(many=True)

    class Meta:
        model = models.Book
        # fields = ["title", "price", "publish_id", "pub_date", "authors"]
        fields = "__all__"
        extra_kwargs = {
            'title': {"error_messages": {"required": "书名内容不能为空"}},
            'publish': {"error_messages": {"required": '出版社不能为空'}},
            'price': {"error_messages": {"required": '价格不能为空'}}
        }
        # depth = 1  # 获取表中的多对多字段深度


class AuthorSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Author
        # fields = ["title", "price", "publish_id", "pub_date", "authors"]
        fields = "__all__"


class PublishSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Publish
        # fields = ["title", "price", "publish_id", "pub_date", "authors"]
        fields = "__all__"
序列化类
from rest_framework import mixins
from rest_framework import generics


class AuthorView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    queryset = models.Author.objects.all()
    serializer_class = serializers.AuthorSerializers

    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 AuthorDetailView(mixins.DestroyModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                       generics.GenericAPIView):
    queryset = models.Author.objects.all()
    serializer_class = serializers.AuthorSerializers

    def get(self, 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)
    path('author/', views.AuthorView.as_view()),
    re_path('^author/(?P<pk>d+)', views.AuthorDetailView.as_view()),

通过使用mixins类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的views.py模块。

class PublishView(generics.ListCreateAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = serializers.PublishSerializers


class PublishDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = serializers.PublishSerializers
    path('publish/', views.PublishView.as_view()),
    re_path('^publish/(?P<pk>d+)', views.PublishDetailView.as_view())

现在使用起来已经非常简洁了,但依然需要将get、post与put、delete分开写成两个类,怎么才能在一个类下就完成这些操作呢,viewsets.ModelViewSet利用url很好的解决了这个问题。

from rest_framework import viewsets


class BookView(viewsets.ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializers.BookSerializers
    path('book/', views.BookView.as_view({'get': 'list', 'post': 'create'})),
    re_path('^book/(d+)', views.BookView.as_view({'get': 'retrieve',
                                                         'put': 'update',
                                                        'patch': 'partial_update',
                                                         'delete': 'destroy'})),
原文地址:https://www.cnblogs.com/aizhinong/p/12543272.html