Restframework从入门到精通(二):Restframework之类视图的编写

460 阅读4分钟

Restframework请求和响应

Restframework扩展了Django默认的 Request 对象,提供了更加的灵活解析,除此之外Restframework还引入了一个 Response响应对象状态码,如翻译文档截图所示:

请求响应说明文档

状态码呢,平常我们得到的结果404什么的我们都知道是找不到界面的意思了,但是Restframework在返回状态码的基础上还给我们返回一个说明

Restframework编写 API视图

函数式编写API视图

Restframework的视图分为函数视图和类视图,这里我就直接用类视图来演示了,因为我开发view视图函数的时候都是用继承from django.views.generic.base import View来开发的,关于通过使用 @api_view 装饰器来对API视图进行开发官网有较明确的说明

函数编写方法说明文档

类的方法来编写API视图

类方法说明文档

官网有详细说明的案例,这里我就直接编写视图代码了

views.py

from .models import Publish
from rest_framework.views import APIView
from .serializers import Publishserializer
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404


class Publish_list(APIView):
    """
        列出所有的出版社或者创建一个新的出版社
    """
    def get(self, request, format=None):
        publish = Publish.objects.all()
        serializer = Publishserializer(publish, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = Publishserializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class PublisherDetail(APIView):
    """
    具体的出版社的查看、修改和删除视图
    """
    def get_object(self, pk):
        try:
            return Publish.objects.get(pk=pk)
        except Publish.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        publish = self.get_object(pk)
        serializer = Publishserializer(publish)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        publish = self.get_object(pk)
        serializer = Publishserializer(publish, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        publish = self.get_object(pk)
        publish.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

然后去编写路由

urls.py

from django.conf.urls import url
from django.contrib import admin
from Book.views import Publish_list,PublisherDetail

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^publish/$',Publish_list.as_view()),
    url(r'^publish/(?P<pk>[0-9]+)/$',PublisherDetail.as_view())
]

配置完成,直接去访问地址

对类方法编写API视图进行优化

mixins类说明

对上面我演示的案例来说,单单只有一个类方法来编写,就要使用到get_objectputdeletepost等方法,如果有很多个API方法,就要使用到很多个重复的方法,所以Restframework整合了这些方法成为一个类,把重复的方法都整合起来,我们只需要修改表就可以了,这样就可以大大的减少代码量

整合的方法

来,让我们康康mixins的源码

部分源码

根据源码所示,model的表名要赋值给queryset,序列化后的字段要赋值给serializer_class,不然就会报错

mixins类里面封装了很多的方法,我们需要用到什么方法的时候就继承里面的哪个方法即可

使用mixins重写view方法

views.py

from .models import Publish
from .serializers import Publishserializer
from rest_framework import mixins
from rest_framework import generics


class Publish_list(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    """
        列出所有的出版社或者创建一个新的出版社
        """
    queryset = Publish.objects.all()
    serializer_class = Publishserializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)


class PublisherDetail(mixins.RetrieveModelMixin,
                      mixins.UpdateModelMixin,
                      mixins.DestroyModelMixin,
                      generics.GenericAPIView):
    """
    具体的出版社的查看、修改和删除视图
    """
    queryset = Publish.objects.all()
    serializer_class = Publishserializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

拿修改后的代码跟原来的一比,代码的逻辑少了很多,querysetserializer_classmixins里面定义好的字段,所以我们把值赋值给这两个字段即可

再访问 http://127.0.0.1:8000/publish/ 试试

使用mixins重写后访问

依然没有任何问题

mixins之再优化

在上述的mixins方法中已经帮我们整合了大部分的方法,已经减少了我们原本的大部分代码,但是还是有优化的地方

我们每次要调用很多个mixins方法的时候,一次要继承三四个类,看起来十分不美观

你想到的Restframework早就想到了,而且还帮你做出了优化

我拿截图的这两个代码来说明,我们一次要继承四个类,所以我们可以直接去继承一个整合类来代替四个类

class Publish_list(generics.ListCreateAPIView):
    """
        列出所有的出版社或者创建一个新的出版社
    """
    queryset = Publish.objects.all()
    serializer_class = Publishserializer

class PublisherDetail(generics.RetrieveUpdateDestroyAPIView):
    """
    具体的出版社的查看、修改和删除视图
    """
    queryset = Publish.objects.all()
    serializer_class = Publishserializer

这个整合的代码的名称很简便易懂,让我们康康源码

哦吼,里面的代码不就是我们刚刚写的吗,直接帮我们把要重复的代码又整合一遍,把原本要十几行代码整合到了两行,我们直接写字段就好了