视图
一、进化
class GenericView(APIView):
"""把视图中可能用到的配置和方法封装起来"""
queryset = None
serializer_class = None
def get_queryset(self):
# 让每次请求来的时候都现查一次数据
return self.queryset.all()
混合类的巧妙使用:
# python mixin(混合类):不能单独使用,和其它类搭配起来使用(利用了Python支持多继承)
class ListMixin(object):
def get(self, request):
queryset = self.get_queryset()
ser_obj = self.serializer_class(queryset, many=True)
return Response(ser_obj.data)
二、超进化
提取混合类,将混合类继续组合!
把增删改查查五哥动作拆分出来,写成独立的混合类。
# python mixin(混合类):不能单独使用,和其它类搭配起来使用(利用了Python支持多继承)
class ListMixin(object):
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
ser_obj = self.serializer_class(queryset, many=True)
return Response(ser_obj.data)
class CreateMixin(object):
def create(self, request, *args, **kwargs):
ser_obj = self.serializer_class(data=request.data)
if ser_obj.is_valid():
ser_obj.save()
return Response("ok")
else:
return Response(ser_obj.errors)
# 获取具体某一条记录
class RetrieveMixin(object):
def retrieve(self, request, pk, *args, **kwargs):
obj = self.get_object(request, pk, *args, **kwargs)
if obj:
# 2. 将书籍对象 序列化成 json格式的数据
ser_obj = self.serializer_class(obj)
# 3. 返回响应
return Response(ser_obj.data)
else:
return Response("无效的id")
class UpdateMixin(object):
def update(self, request, pk, *args, **kwargs):
obj = self.get_object(request, pk, *args, **kwargs)
if obj:
ser_obj = self.serializer_class(instance=obj, data=request.data, partial=True) # form组件中也有类似的实现
if ser_obj.is_valid():
ser_obj.save()
return Response(ser_obj.data)
else:
return Response(ser_obj.errors)
else:
return Response("无效的id")
class DestroyMixin(object):
def destroy(self, request, pk, *args, **kwargs):
obj = self.get_object(request, pk, *args, **kwargs)
if obj:
obj.delete()
return Response("删除成功")
else:
return Response("无效的id")
具体的视图:
# 作者
class AuthorListView(GenericView, ListMixin, CreateMixin):
queryset = models.Author.objects.all()
serializer_class = AuthorModelSerializer
class AuthorDetailView(RetrieveView, UpdateMixin, DestroyMixin):
queryset = models.Author.objects.all()
serializer_class = AuthorModelSerializer
其实内置已经提供了
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
三、究极进化
一张表要写两个视图,定义两次 queryset和serializer_class 重复!
from rest_framework.viewsets import GenericViewSet
重写了as_view()
方法,实现了根据请求的方法执行具体的类方法
路由注册的时候,利用actions参数,实现路由的定向分发 而不是简单的 反射
url(r'authors/$', views.AuthorViewSet.as_view(actions={'get': 'list', 'post': 'create'})), # 作者列表
url(r'authors/(?P<pk>d+)/$', views.AuthorViewSet.as_view(
actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})
), # 作者详情
路由都重复写两条:
还可以利用内置的DefaultRouter来实现路由的注册
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('authors', views.AuthorViewSet)
urlpatterns += router.urls
四、总结