DRF中的视图

请求对象

REST框架引入了一个扩展了常规HttpRequest的请求对象, 并提供更灵活的请求解析。请求对象的核心功能是属性request.data,与request.POST类似,但对于WebAPIs更有用。

request.POST  # Only handles form data.  Only works for 'POST' method.
request.data  # Handles arbitrary data.  Works for 'POST', 'PUT' and 'PATCH' methods.

响应对象

REST framework还引入了一个响应对象,这是一种TemplateResponse类型,它接受未渲染的内容,并使用内容协商来确定返回给客户端的正确内容类型。

return Response(data)  # Renders to content type as requested by the client.

状态码

在视图中使用数字HTTP状态码并不总是容易读懂,而且当使用了错误的状态码不容易发现。而REST框架为每个状态代码提供了更显式的标识符:

from rest_framework import status

在这里插入图片描述

drf中的函数视图

REST框架提供了一个装饰器@api_view,可以来装饰基本的函数视图。
这个装饰器提供了一些功能,比如确保在视图中接收到请求实例,并向响应对象添加上下文,以便可以执行内容协商。
装饰器还提供了一些行为,比如在适当的时候返回405 Method Not Allowed响应,以及处理当request.data输入不正确数据时发生的任何ParseError异常。
举例:
以前面创建过的序列化及项目为例,通过drf的函数视图来实现项目的增删改查

from project2s.serializers import ProjectSerializers
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status

@api_view(['GET', 'POST'])
def list_create(request):

	“”“”查询或创建方法“”“
	
    if request.method == 'GET':
        s = Student.objects.all() # 查询集
        ser = ProjectSerializers(s, many=True) #序列化器
        return Response(ser.data) 
    elif request.method == 'POST':
        ser = ProjectSerializers(request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data, status=status.HTTP_201_CREATED)
        else:
            return JsonResponse(ser.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def update_detail_delete(request, pk):
    try:
        obj = Student.objects.get(pk=pk)
    except Student.DoesNotExist:
        return Response(status=status.HTTP_400_BAD_REQUEST)
    if request.method == 'GET':
        ser = ProjectSerializers(obj)
        return Response(ser.data)
    elif request.method == 'PUT':
        ser = ProjectSerializers(obj, request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        else:
            return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        obj.delete()
        return JsonResponse({'message': '删除成功'}, status=status.HTTP_204_NO_CONTENT)

请求结果:
在这里插入图片描述

配置url可选格式后缀

可以通过添加格式后缀返回对应格式的内容

http http://127.0.0.1:8000/student.json  # JSON suffix
http http://127.0.0.1:8000/student.api   # Browsable API suffix

导入 format_suffix_patterns处理下路由

from django.urls import path
from project2s import views
from rest_framework.urlpatterns import format_suffix_patterns

app_name = 'project2s'
urlpatterns = [
    path('students/', views.list_create),  # 创建或展示
    path('students/<int:pk>/', views.update_detail_delete)  # 删除或显示
]
urlpatterns = format_suffix_patterns(urlpatterns)

views.py中的视图函数需要加上format=None参数
当我们配置处理这个路由之后,当直接使用浏览器访问接口时,它会返回该资源的html格式表示。
http http://127.0.0.1:8000/student.api :
在这里插入图片描述
http http://127.0.0.1:8000/student.json:
在这里插入图片描述

drf中的类视图

编写类视图继承APIView基类:


from django.http import Http404
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from project2s.serializers import ProjectSerializers
from project2s.models import Student
#类视图

class ListCreateView(APIView):
    def get(self, request, format=None):
        obj = Student.objects.all()
        ser = ProjectSerializers(obj, many=True)
        return Response(ser.data)

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


class UpdatePutDeleteDetailView(APIView):

    def get_object(self, pk):
        try:
            return Student.objects.get(pk=pk)
        except Student.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        obj = self.get_object(pk)
        ser = ProjectSerializers(obj)
        return Response(ser.data)

    def put(self, request, pk, format=None):
        obj = self.get_object(pk)
        ser = ProjectSerializers(obj, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data, status=status.HTTP_204_NO_CONTENT)

        return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)

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

基于类的视图重写API

当有多个模型需要编写类视图,由上可见代码部分可复用,而drf框架提供了很多基类进行了高度封装,只需要继承即可。

from rest_framework import generics, mixins

generics中提供了获取模型对象及序列化器的类,需要通过queryset,serializer_class指定:
在这里插入图片描述

mixins中封装好的类如下:
创建:
在这里插入图片描述获取:
在这里插入图片描述
在这里插入图片描述
更新:
在这里插入图片描述
删除:
在这里插入图片描述
通过视图类继承这些类并调用其中方法即可:

from rest_framework import  generics, mixins
from project2s.models import Student
from project2s.serializers import ProjectSerializers

# 类视图
class ListCreateView(generics.GenericAPIView,
				     mixins.ListModelMixin,
				     mixins.CreateModelMixin):
				     
    queryset = Student.objects.all() 
    serializer_class = ProjectSerializers
    
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs) # 调用ListModelMixin类中的self.list()

    def post(self, request, *args, **kwargs):
       return self.create(request, *args, **kwargs) # 调用CreateModelMixin类中的self.create()


class UpdatePutDeleteDetailView(generics.GenericAPIView,
                                mixins.RetrieveModelMixin,
                                mixins.UpdateModelMixin,
                                mixins.DestroyModelMixin):
    queryset = Student.objects.all()
    serializer_class = ProjectSerializers

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs) # 调用RetrieveModelMixin类中的self.retrieve()

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs) # 调用UpdateModelMixin类中的self.update()

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs) # 调用DestroyModelMixin类中的self.destroy()

还没结束,以上编写的继承关系在generics类中其实已经封装好了,如下:
在这里插入图片描述
在这里插入图片描述
所以只需要继承generics中的类即可:

from project2s.models import Student
from project2s.serializers import ProjectSerializers
from rest_framework import status, generics, mixins


# 类视图
class ListCreateView(generics.ListCreateAPIView):
    queryset = Student.objects.all()
    serializer_class = ProjectSerializers

class UpdatePutDeleteDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Student.objects.all()
    serializer_class = ProjectSerializers

访问结果:
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

久醉绕心弦,

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值