06 视图函数封装(二)

编辑本文章

重写View视图函数,将多个类进行合并

from rest_framework import views
# APIView
from rest_framework import generics
# 公共的通用的视图类
from rest_framework import mixins
# 混合继承类
from rest_framework import viewsets
# ModelViewSet

1、路由分发

from django.urls import path
from DRFServer.views import BookView,BookEditView,BookModelViewSet
urlpatterns=[
    # path('list/',BookView.as_view()),
    #Django 2.0版本前写法
    # path('retrieve/(?P<id>\d+)',BookEditView.as_view()),
    # Django 2.0后的写法
    # path('retrieve/<int:id>',BookEditView.as_view()),
    path('list/',BookModelViewSet.as_view({"get":"list","post":"create"})),
    path("retrieve/<int:id>",BookModelViewSet.as_view({"get":"retrieve","put":"update","delete":"destroy"}))
]
View Code

给as_view()传入字典,让对应请求使用自定义方法,前提是View必须继承ViewSetMixin类

2、View类修改继承

from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from django.core import serializers
from DRFServer.models import Book, Publisher
import json
# Create your views here.
from django.views import View
from rest_framework.views import APIView
from rest_framework.response import Response
from DRFServer.serializers import BookSerializer


# class BookView(View):
# 版本一,使用values和JsonResponse实现序列号
# def get(self,request):
#     book_list=Book.objects.values("id","title","pub_time","publisher","author")
#     # queryset无法直接被json系列化,先对其list
#     book_list=list(book_list)
#     ret=[]
#     for book in book_list:
#         publisher_id=book["publisher"]
#         publisher_obj=Publisher.objects.filter(id=publisher_id).first()
#         book["publisher"]={"id":publisher_id,"title":publisher_obj.title}
#         ret.append(book)
#     # ensure_ascii=False避免中文乱码
#     # ret=json.dumps(book_list,ensure_ascii=False)
#     # return HttpResponse(ret)
#     return JsonResponse(ret,safe=False,json_dumps_params={"ensure_ascii":False})
# 版本二,使用django serializers实现序列号
# def get(self,request):
#     book_list=Book.objects.all()
#     ret=serializers.serialize("json",book_list,ensure_ascii=False)
#     return HttpResponse(ret)

class GenericAPIView(APIView):
    #这里其实在具体View中去重新赋值,self去查找就不会查找到None
    query_set = None
    serializer_class = None

    def get_queryset(self):
        return self.query_set

    def get_obj(self, id):
        return self.get_queryset().filter(pk=id).first()

    def get_serializer(self, *args, **kwargs):
        return self.serializer_class(*args, **kwargs)


# 定义混合类
class ListModelMixin(object):
    def list(self, request):
        book_list = self.get_queryset()
        ret = self.get_serializer(book_list, many=True)
        return Response(ret.data)

class CreateModelMixin(object):
    def create(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)

class RetrieveModelMixin(object):
    def retrieve(self, request, id):
        obj = self.get_obj(id)
        ret = self.get_serializer(obj)
        return Response(ret.data)

class UpdateModelMixin(object):
    def update(self, request, id):
        obj = self.get_obj(id)
        serializers = self.get_serializer(instance=obj, data=request.data, partial=True)
        if serializers.is_valid():
            serializers.save()
            return Response(serializers.data)
        return Response(serializers.errors)

class DestroyModelMixin(object):
    def destroy(self, request, id):
        obj = self.get_obj(id)
        obj.delete()
        return Response("")

class ListCreateModel(GenericAPIView,ListModelMixin,CreateModelMixin):
    pass

class BookView(ListCreateModel):
    query_set = Book.objects.all()
    serializer_class = BookSerializer
    def get(self, request):
        # book_obj=Book.objects.first()
        # 一条数据
        # ret=BookSerializer(book_obj)
        # book_list=Book.objects.all()
        # 多条数据
        # ret=BookSerializer(book_list,many=True)
        # book_list=self.get_queryset()
        # ret=BookSerializer(book_list,many=True)
        # return Response(ret.data)
        return self.list(request)
    def post(self, request):
        # serializer=BookSerializer(data=request.data)
        # if serializer.is_valid():
        #     serializer.save()
        #     return Response(serializer.data)
        # else:
        #     return Response(serializer.errors)
        return self.create(request)

class RetrieveUpdateDestroyModel(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    pass

class BookEditView(RetrieveUpdateDestroyModel):
    serializer_class = BookSerializer
    query_set = Book.objects.all()
    def get(self, request, id):
        # book_obj=Book.objects.filter(id=id).first()
        # ret=BookSerializer(book_obj)
        # return Response(ret.data)
        return self.retrieve(request, id)
    def put(self, request, id):
        return self.update(request, id)
        # data=request.data
        # book_obj = Book.objects.filter(id=id).first()
        # partial=True允许部分更新
        # serializers=BookSerializer(instance=book_obj,data=data,partial=True)
        # if serializers.is_valid():
        # 方式一
        # serializers.update(book_obj,serializers.validated_data)
        # 方式二
        # serializers.save()
        #     return Response(serializers.data)
        # else:
        #     return Response(serializers.errors)
    def delete(self, request, id):
        # book_obj=Book.objects.filter(id=id).first()
        # book_obj.delete()
        # return Response("")
        return self.destroy(request, id)

from rest_framework.viewsets import ViewSetMixin
class BookModelViewSet(ViewSetMixin,GenericAPIView,ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
    serializer_class = BookSerializer
    query_set = Book.objects.all()
    #路由中对应的方法,在继承中找即可

    
View Code

使用View类继承ViewSetMixin类,该类重写了as_view()方法

 3、使用框架提供的ModelViewSet

  URL修改

  

4、DRF路由

使用drf提供的DefaultRouter生成urls,这样会暴露出全部api,一般采用自己配置

 

posted @ 2019-06-25 09:27  丫丫625202  阅读(118)  评论(0编辑  收藏  举报