Django REST framework--类视图

基于类的视图

项目开发中要不断思考如何让代码保持高内聚,低耦合,因此优化代码的道路上一直都不停歇。目前开发的视图是基于函数形式的,特点是灵活,缺点是功能冗余性大,面对常见的增删改查往往要写重复的代码。

REST框架可以用基于类的视图来优化代码结构

APIView类视图

用类重写视图,继承REST框架的APIView类

sqtp应用app目录下的views.py文件下将request_listrequest_detail两个视图函数修改为类视图

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt    # 跨站攻击防护,接口白名单处理
from rest_framework import status
from rest_framework.parsers import JSONParser       # 序列化
from rest_framework.response import Response

from sqtp.models import Request     # 模型
from sqtp.serializers import RequestSerializer      # 自定义的序列化类
from rest_framework.decorators import api_view
from rest_framework.views import APIView  # 继承APIView类视图

# 改写 request_list 视图方法
class RequestList(APIView):
    '''
    查询所有数据和新增单个数据的功能
    '''
    def get(self,request,format=None):
        # 获取序列化器--针对当前数据模型的所有数据
        serializer = RequestSerializer(Request.objects.all(), many=True)
        return Response(serializer.data)  # 使用DRF框架的响应对象,自动分配返回格式

    # 处理新增请求
    def post(self,request,format=None):
        # 构建序列化器,反序列化,将request.data数据恢复成正常的对象实例
        serializer = RequestSerializer(data=request.data)
        # 校验数据是否合法
        if serializer.is_valid():
            serializer.save()
            # 新增成功返回新增数据状态码201
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        # 新增失败返回错误信息400,请求数据有问题
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


# 改写 request_detail 视图方法
class RequestDetail(APIView):

    # 覆盖父类的get_object方法实现
    def get_object(self,_id):
        try:
            return Request.objects.get(id=_id)
        except Exception:
            return Response(status=status.HTTP_404_NOT_FOUND)  # 返回错误状态码

    def get(self,request,_id,format=None):
        # 序列化,将数据对象转化为json格式
        req_boj = self.get_object(_id)
        # 如果是异常响应,直接返回
        if isinstance(req_boj,Response):
            return req_boj
        serializer = RequestSerializer(req_boj)
        return Response(data=serializer.data)

    def put(self,request,_id,format=None):
        # 采用序列化器实现修改,这里与查询不同的是,还需要把待修改的数据放到序列化器里进行覆盖
        req_boj = self.get_object(_id)
        # 如果是异常响应,直接返回
        if isinstance(req_boj, Response):
            return req_boj
        serializer = RequestSerializer(req_boj, data=request.data)
        # 判断data中的数据是否符合要求
        if serializer.is_valid():
            # 若符合要求则进行保存操作
            serializer.save()
            # 将修改成功的状态码返回
            return Response(serializer.data, status=status.HTTP_200_OK)
        # 修改失败返回错误信息400,修改传递的数据有问题
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self,request,_id,format=None):
        req_boj = self.get_object(_id)
        # 如果是异常响应,直接返回
        if isinstance(req_boj, Response):
            return req_boj
        req_boj.delete()  # 获取数据后进行删除
        # 将删除成功的状态码返回
        return Response(status=status.HTTP_204_NO_CONTENT)

修改sqtp应用app目录下的urls.py文件

from django.urls import path
from sqtp import views as sqtp_view
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = [
  path('requests/',sqtp_view.RequestList.as_view()),  # 视图类需要调用 as_view转化
  path('requests/<int:_id>',sqtp_view.RequestDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns) # 重写url

行命令python manage.py runserver 0.0.0.0:8888启动项目,在浏览器中输入http://127.0.0.1:8888/requests/,可以发现页面返回内容与视图函数,是一样的

generics通用类视图

使用类视图的一个好处就是可以复用相同的功能,只需传入指定的参数即可。在上面的案例中,增删改查的逻辑行为都是确定的。

REST框架为我们封装好了逻辑,可以用更少的代码来封装视图,比如采用generics模块的通用视图:通过generics.ListCreateAPIViewm 实现列出所有和新增;通过generics.RetrieveUpdateDestroyAPIView获取单个、更新和删除功能

sqtp应用app目录下的views.py文件下将request_listrequest_detail两个视图函数修改为generics通用类视图

from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView   # 继承generics通用类视图

# 改写 request_list 视图方法
class RequestList(ListCreateAPIView):
    queryset = Request.objects.all()    # 数据的查询集
    serializer_class = RequestSerializer


# 改写 request_detail 视图方法
class RequestDetail(RetrieveUpdateDestroyAPIView):
    queryset = Request.objects.all()  # 数据的查询集
    serializer_class = RequestSerializer

由于是 RequestDetail视图类是继承RetrieveUpdateDestroyAPIView类,所以参数id的名称要为pk,这是底层代码GenericAPIView类中的要求限制lookup_field = 'pk'

否则,浏览器中输入http://127.0.0.1:8888/requests/43,就会产生报错,提示修改url配置

AssertionError: Expected view RequestDetail to be called with a URL keyword argument named "pk". Fix your URL conf, or set the `.lookup_field` attribute on the view correctly.

修改sqtp应用app目录下的urls.py文件,将requests/<int:_id>修改为requests/<int:pk>

from django.urls import path
from sqtp import views as sqtp_view
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = [
  path('requests/',sqtp_view.RequestList.as_view()),  # 视图类需要调用 as_view转化
  path('requests/<int:pk>',sqtp_view.RequestDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns) # 重写url

重启服务,测试增删改查,依然OK!

可以发现,数据详情的编辑页面还支持按字段进行编辑,这是通用类视图提供的效果。

在这里插入图片描述

视图集

通过使用generics通用类视图,代码量已经减少到了不到10行,优化后的视图代码依然存在重复的部分,这部分的代码依旧可以继续优化,用ViewSet(视图集)代替View类重构视图

sqtp应用app目录下的views.py文件下将RequestLisRequestDetail两个视图类修改一个

from rest_framework import viewsets

class RequestViewSet(viewsets.ModelViewSet):
    queryset = Request.objects.all()  # 数据的查询集
    serializer_class = RequestSerializer

使用REST ViewSets 的抽象后,开发人员可以集中精力对API的状态和交互进行建模,并根据常规约定自动处理URL构造。

ViewSet 类与 View 类几乎相同,不同之处在于它们提供诸如 read 或 update 之类的操作,而不是 get 或 put 等方法处理程序。

一个 ViewSet 类只绑定到一组方法处理程序,当它被实例化成一组视图的时候,通常通过使用一个 Router 类来代替自己定义复杂的URL。

DRF框架路由

因为使用的是 ViewSet 类而不是 View 类,所以连常规的URL设计都可以偷懒了。利用rest框架 的router,可以自动生成路由列表。

修改sqtp应用app目录下的urls.py文件

from django.urls import path,include
from sqtp import views as sqtp_view
# 使用rest框架自带的路由器生成路由列表
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'requests',sqtp_view.RequestViewSet)

urlpatterns = [
    path('',include(router.urls))
]

router的作用是根据注册的路由前缀,帮助你自动生成诸如此类的路由列表,根据正则匹配参数、后缀等内容

^requests/$ [name='request-list']
^requests\.(?P<format>[a-z0-9]+)/?$ [name='request-list']
^requests/(?P<pk>[^/.]+)/$ [name='request-detail']
^requests/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='request-detail']

重启服务,测试增删改查,依然OK!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django REST Framework Cache是一个Django框架的扩展,用于缓存REST API的响应数据。它提供了一种简单的方式来缓存API视图的响应,以减少数据库查询和加快请求的响应速度。 使用Django REST Framework Cache,你可以通过在视图视图函数上添加装饰器来启用缓存。这个扩展支持多种缓存后端,包括内存缓存、数据库缓存和文件缓存等。你可以根据你的需求选择适合的缓存后端。 为了使用Django REST Framework Cache,你需要在你的Django项目中安装并配置它。你可以通过pip安装它: ``` pip install djangorestframework-cache ``` 安装完成后,在你的项目的settings.py文件中添加以下配置: ```python INSTALLED_APPS = [ ... 'rest_framework_cache', ] CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', } } REST_FRAMEWORK_CACHE = { 'DEFAULT_CACHE_BACKEND': 'default', } ``` 然后,在你的API视图或函数上使用`@cache_response`装饰器来启用缓存: ```python from rest_framework.decorators import api_view from rest_framework_cache.decorators import cache_response @api_view(['GET']) @cache_response(timeout=60*60*24) # 缓存一天 def my_view(request): ... ``` 这样,当该API被访问时,响应数据将会被缓存,并在下次请求相同的API时直接返回缓存的响应数据,而不需要执行相同的查询操作。 通过使用Django REST Framework Cache,你可以有效地提高REST API的性能和响应速度,并减少对数据库的负载。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值