Restful API学习Day3 - DRF视图

视图

一、进化

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

四、总结

1547439468196

867021-20190113231720487-805070869

猜你喜欢

转载自www.cnblogs.com/russellyoung/p/Restful-API-xue-xiDay3--DRF-shi-tu.html