视图家族概况

视图家族概况

"""
views:基本视图
    APIView
    
generics:工具视图
    GenericAPIView 该家族的基类
        将 queryset 和 serializer_class 封装成类属性,提供了三个方法
        get_queryset() | get_object() | get_serializer(*args, **kwargs)
        ps:在视图中如果定义好了 queryset = models.Book.objects.filter(is_delete=False).all()
        那么 get_queryset和get_object都可以拿到对象,get_object会自动取根据pk进行取值。
        

    GenericAPIView众多子类
        继承 (mixins中若干功能类, GenericAPIView基类)
        提供 get | post | put | patch | delete 五大接口
        eg:RetrieveUpdateAPIView就可以完成 单取(get),单局部(patch)及整体(put)修改

mixins:视图工具集
    五大工具类:
        RetrieveModelMixin:retrieve 单取
        ListModelMixin:list 群取
        CreateModelMixin:create 单增
        UpdateModelMixin:update 单整体改  partial_update 单局部改
        DestroyModelMixin:destroy 单删


viewsets:视图集
    ViewSetMixin:视图集工具 - 重写as_view - 将 请求方式 映射到视图类中的 指定方法
        .as_view({'get': 'retrieve', 'delete': 'remove_obj'})
    GenericViewSet:与模型类有关的接口视图集 - 可以从mixins那继承功能,也可以自定义功能
    ViewSet:与模型类无关或不是标准模型类接口 - 一般都是自定义功能

开发中常用类
views:APIView
generics:ListAPIView, ...
viewsets:
class GenericViewSet(ViewSetMixin, #路由分发
                    generics.GenericAPIView #将 queryset 和 serializer_class 封装成类属性,提供了三个方法
                    ):
                    

class ModelViewSet(mixins.CreateModelMixin, # create 单增
                   mixins.RetrieveModelMixin, # retrieve 单取
                   mixins.UpdateModelMixin, # update 单整体改  partial_update 单局部改
                   mixins.DestroyModelMixin, # destroy 单删
                   mixins.ListModelMixin, # list 群取
                   GenericViewSet):

ps:其余什么登陆。。。群删 群增 群改 自己实现
"""

路由层:api/url.py

from django.conf.urls import url
from . import views
urlpatterns = [
    # views
    url(r'^books/$', views.BookAPIView.as_view()),
    url(r'^books/(?P<pk>.*)/$', views.BookAPIView.as_view()),

    # generics
    url(r'^v1/books/$', views.BookGenericAPIView.as_view()),
    url(r'^v1/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
	
    # mixins + generics
    url(r'^v2/books/$', views.BookMixinsGenericAPIView.as_view()),
    url(r'^v2/books/(?P<pk>.*)/$', views.BookMixinsGenericAPIView.as_view()),
	
    # 系统整合mixins、generics
    url(r'^v3/books/$', views.BookRetrieveUpdateAPIView.as_view()),
    url(r'^v3/books/(?P<pk>.*)/$', views.BookRetrieveUpdateAPIView.as_view()),

    # viewsets
    url(r'^v4/books/$', views.BookGenericViewSet.as_view({
        'get': 'list',
        'post': 'create'
    })),
    url(r'^v4/books/(?P<pk>.*)/$', views.BookGenericViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'patch': 'partial_update',
        'delete': 'remove_book'
    })),
]

模型层:api/models.py

# 没有变化

序列化层:api/serializers.py

from rest_framework import serializers
from . import models
class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = ('name', 'price', 'publish', 'authors')
        extra_kwargs = {
            'publish': {
                # 数据库有默认值,必须反序列化的字段,要设置required=True
                'required': True,  
                'write_only': True
            },
            'authors': {
                'required': True,
                'write_only': True
            }
        }

视图层:api/views.py

from rest_framework import views, generics, mixins, viewsets
from . import models, serializers
from utils.response import APIResponse


# 基础
class BookAPIView(views.APIView):
    def get(self, request, *args, **kwargs):
        book_query = models.Book.objects.filter(is_delete=False).order_by('-id').all()
        book_ser = serializers.BookModelSerializer(book_query, many=True)
        return APIResponse(0, 'ok', results=book_ser.data)

    def post(self, request, *args, **kwargs):
        book_ser = serializers.BookModelSerializer(data=request.data)
        book_ser.is_valid(raise_exception=True)
        book_obj = book_ser.save()
        return APIResponse(0, 'ok', results=serializers.BookModelSerializer(book_obj).data)

# v1 generics - 视图基类
class BookGenericAPIView(generics.GenericAPIView):
    queryset = models.Book.objects.filter(is_delete=False).order_by('-id')
    serializer_class = serializers.BookModelSerializer

    def get(self, request, *args, **kwargs):
        if 'pk' in kwargs:
            book_obj = self.get_object()
            book_ser = self.get_serializer(book_obj)
            return APIResponse(0, 'ok', results=book_ser.data)
        book_query = self.get_queryset()
        book_ser = self.get_serializer(book_query, many=True)
        return APIResponse(0, 'ok', results=book_ser.data)

    def post(self, request, *args, **kwargs):
        book_ser = self.get_serializer(data=request.data)
        book_ser.is_valid(raise_exception=True)
        book_obj = book_ser.save()
        return APIResponse(0, 'ok', results=self.get_serializer(book_obj).data)

# v2 mixins - 工具集
class BookMixinsGenericAPIView(mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    queryset = models.Book.objects.filter(is_delete=False).order_by('-id')
    serializer_class = serializers.BookModelSerializer
    def get(self, request, *args, **kwargs):
        if 'pk' in kwargs:
            response = self.retrieve(request, *args, **kwargs)
        else:
            response = self.list(request, *args, **kwargs)
        return APIResponse(0, 'ok', results=response.data)

    def post(self, request, *args, **kwargs):
        response = self.create(request, *args, **kwargs)
        return APIResponse(0, 'ok', results=response.data)

# v3 视图基类子类 - 工具视图类
class BookRetrieveUpdateAPIView(generics.RetrieveUpdateAPIView):
    queryset = models.Book.objects.filter(is_delete=False).order_by('-id')
    serializer_class = serializers.BookModelSerializer


# v4 视图集 - 快速实现模型类五大接口 - 自定义删除方法
class BookGenericViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
    queryset = models.Book.objects.filter(is_delete=False).order_by('-id')
    serializer_class = serializers.BookModelSerializer

    def remove_book(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        try:
            book_obj = models.Book.objects.get(is_delete=False, pk=pk)
            book_obj.is_delete = True
            book_obj.save()
            return APIResponse(0, '删除成功')
        except:
            return APIResponse(1, '删除失败')
posted @ 2019-11-19 14:55  张明岩  阅读(160)  评论(0编辑  收藏  举报