视图家族概况
"""
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, '删除失败')