zoukankan      html  css  js  c++  java
  • drf03 drf视图中提供的请求类和响应类

    drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作。所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用。

    Django REST framwork 提供的视图的主要作用:

    • 控制序列化器的执行(检验、保存、转换数据)

    • 控制数据库查询的执行

    • 调用请求类和响应类[这两个类也是由drf帮我们再次扩展了一些功能类。]

    为了方便我们学习,所以先创建一个子应用req

    python manage.py startapp req

     

    请求与响应

      1. Request

      REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的Request类的对象。

      REST framework 提供了Parser解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进行parse解析,解析为类字典[QueryDict]对象保存到Request对象中。

      Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果。

      无论前端发送的哪种格式的数据,我们都可以以统一的方式读取数据。

      常用属性

      1).data

      request.data 返回解析之后的请求体数据。类似于Django中标准的request.POSTrequest.FILES属性,但提供如下特性:

    • 包含了解析之后的文件和非文件数据

    • 包含了对POST、PUT、PATCH请求方式解析后的数据

    • 利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据

      2).query_params

      request.query_params与Django标准的request.GET相同,只是更换了更正确的名称而已。

     

      2. Response

    rest_framework.response.Response

    REST framework提供了一个响应类Response,使用该类构造响应对象时,响应的具体数据内容会被转换(render渲染)成符合前端需求的类型。

    REST framework提供了Renderer 渲染器,用来根据请求头中的Accept(接收数据类型声明)来自动转换响应数据到对应格式。如果前端请求中未进行Accept声明,则会采用默认方式处理响应数据,我们可以通过配置来修改默认响应格式。

    REST_FRAMEWORK = {
       'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
           'rest_framework.renderers.JSONRenderer',  # json渲染器
           'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
      )
    }

      2.1 构造方式

    Response(data, status=None, template_name=None, headers=None, content_type=None)

    data数据不要是render处理之后的数据,只需传递python的内建类型数据即可,REST framework会使用renderer渲染器处理data

    data不能是复杂结构的数据,如Django的模型类对象,对于这样的数据我们可以使用Serializer序列化器序列化处理后(转为了Python字典类型)再传递给data参数。

    参数说明:

    • data: 为响应准备的序列化处理后的数据;

    • status: 状态码,默认200;

    • template_name: 模板名称,如果使用HTMLRenderer 时需指明;

    • headers: 用于存放响应头信息的字典;

    • content_type: 响应数据的Content-Type,通常此参数无需传递,REST framework会根据前端所需类型数据来设置该参数。

      2.2 常用属性

      1).data

      传给response对象的序列化后,但尚未render处理的数据

      2).status_code

      状态码的数字

      3).content

      经过render处理后的响应数据

     

      2.3 状态码

      为了方便设置状态码,REST framewrok在rest_framework.status模块中提供了常用状态码常量。

      1)信息告知 - 1xx
    HTTP_100_CONTINUE
    HTTP_101_SWITCHING_PROTOCOLS
      2)成功 - 2xx
    HTTP_200_OK
    HTTP_201_CREATED
    HTTP_202_ACCEPTED
    HTTP_203_NON_AUTHORITATIVE_INFORMATION
    HTTP_204_NO_CONTENT
    HTTP_205_RESET_CONTENT
    HTTP_206_PARTIAL_CONTENT
    HTTP_207_MULTI_STATUS
      3)重定向 - 3xx
    HTTP_300_MULTIPLE_CHOICES
    HTTP_301_MOVED_PERMANENTLY
    HTTP_302_FOUND
    HTTP_303_SEE_OTHER
    HTTP_304_NOT_MODIFIED
    HTTP_305_USE_PROXY
    HTTP_306_RESERVED
    HTTP_307_TEMPORARY_REDIRECT
      4)客户端错误 - 4xx
    HTTP_400_BAD_REQUEST
    HTTP_401_UNAUTHORIZED
    HTTP_402_PAYMENT_REQUIRED
    HTTP_403_FORBIDDEN
    HTTP_404_NOT_FOUND
    HTTP_405_METHOD_NOT_ALLOWED
    HTTP_406_NOT_ACCEPTABLE
    HTTP_407_PROXY_AUTHENTICATION_REQUIRED
    HTTP_408_REQUEST_TIMEOUT
    HTTP_409_CONFLICT
    HTTP_410_GONE
    HTTP_411_LENGTH_REQUIRED
    HTTP_412_PRECONDITION_FAILED
    HTTP_413_REQUEST_ENTITY_TOO_LARGE
    HTTP_414_REQUEST_URI_TOO_LONG
    HTTP_415_UNSUPPORTED_MEDIA_TYPE
    HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
    HTTP_417_EXPECTATION_FAILED
    HTTP_422_UNPROCESSABLE_ENTITY
    HTTP_423_LOCKED
    HTTP_424_FAILED_DEPENDENCY
    HTTP_428_PRECONDITION_REQUIRED
    HTTP_429_TOO_MANY_REQUESTS
    HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
    HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
      5)服务器错误 - 5xx
    HTTP_500_INTERNAL_SERVER_ERROR
    HTTP_501_NOT_IMPLEMENTED
    HTTP_502_BAD_GATEWAY
    HTTP_503_SERVICE_UNAVAILABLE
    HTTP_504_GATEWAY_TIMEOUT
    HTTP_505_HTTP_VERSION_NOT_SUPPORTED
    HTTP_507_INSUFFICIENT_STORAGE
    HTTP_511_NETWORK_AUTHENTICATION_REQUIRED
    from django.http import HttpResponse
    from django.views import View
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    
    """drf提供的请求和响应类只能在drf封装过的子视图类中使用,也就是说不能在django.views.View中使用"""
    """只要类视图直接或者间接集成了APIView,则视图方法中使用的request,就是rest_framework.request.Request
    同时,只有在APIView的子视图类中才可以使用 rest_framework.response.Response响应类
    """
    # 文本根式的状态码
    from rest_framework import status
    class StudentAPIView(APIView):
        def get(self,request):
    
            # 获取get参数
            print(request.query_params)
            """
            <QueryDict: {'name': ['API'], 'age': ['100']}>
            """
            return Response({"message":"ok"},status=status.HTTP_204_NO_CONTENT,headers={"COMPANY":"oldboy"})
    
        def post(self,request):
            # 获取post数据
            print(request.data)
            """
            <QueryDict: {'name': ['小黑'], 'age': ['51'], 'sex': ['0']}>
            """
    
            # 获取一个参数值,get参数的获取也是一样用户
            data = request.data.get("lve")
            print(data)
            """美女"""
            # 获取多个参数值,get参数的获取也是一样用户
            # 使用时注意,如果客户端提交的数据时json,则request会自动转换成字典数据,就不再提供getlist方法了.
            data = request.data.getlist("lve")
            print(data)
            # """['篮球', '睡觉', '美女']"""
    
            return Response({"message":"ok"})
    
    
    """以前的django提供的类视图/函数视图,获取json数据"""
    import json
    class StudentView(View):
        def post(self,request):
            """获取post提交的json数据"""
            # request.POST 只能获取表单数据
            # 获取json类型只能通过body来获取
            data_byte = request.body
    
            data_string = data_byte.decode()
    
            # 通过json进行转换
            data_dict = json.loads(data_string)
            print(data_dict)
            """{'name': 'xiaomingf', 'age': 12, 'sex': 1}"""
            return HttpResponse({"message":"ok"})
    req/views.py
    from django.urls.conf import path
    from . import views
    urlpatterns = [
        path(r"student/",views.StudentAPIView.as_view()),
        path(r"stu/",views.StudentView.as_view()),
    ]
    req/urls.py
    from django.contrib import admin
    from django.urls import path,include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path("stu/",include("students.urls"))
    ]
    urls.py

    使用视图结合序列化器提供基本的5个API接口(增、删、改、查)

    以下两个类配合使用

    from rest_framework.response import Response
    from rest_framework.views import APIView

    from django.shortcuts import render
    from rest_framework import status
    from rest_framework.response import Response
    from rest_framework.views import APIView
    from students.models import Student
    from .serializers import StudentModelSerializer
    # Create your views here.
    class StudentsAPIView(APIView):
    
        def get(self,request):
            """获取所有学生信息"""
            data_list = Student.objects.all()
    
            """
            1. 获取一个数据,传递instance参数
               获取多个数据,传递instance, many=True
            2. 更新数据,传递instance和data参数
               部分字段更新,可以增加传递 partial=True
            3. 添加数据,传递data参数
            4. 删除数据,不需要使用序列化器类
            """
    
            serializer = StudentModelSerializer(instance=data_list,many=True)
    
            return Response(serializer.data)
    
        def post(self,request):
            """添加学生信息"""
            data = request.data
    
            serializer = StudentModelSerializer(data=data)
    
            serializer.is_valid(raise_exception=True)
    
            instance = serializer.save()
    
            serializer = StudentModelSerializer(instance=instance)
    
            return Response(serializer.data,status=status.HTTP_201_CREATED)
    
    
    class StudentAPIView(APIView):
    
        def get(self,request,pk):
    
            instance = Student.objects.get(pk=pk)
    
            serializer = StudentModelSerializer(instance=instance)
    
            return Response(serializer.data)
    
        def put(self,request,pk):
            """更新学生信息"""
            data = request.data
    
            student = Student.objects.get(pk=pk)
    
            serializer = StudentModelSerializer(instance=student, data=data,partial=True)
    
            serializer.is_valid(raise_exception=True)
    
            instance = serializer.save()
    
            serializer = StudentModelSerializer(instance=instance)
    
            return Response(serializer.data)
    
    
        def delete(self,request,pk):
    
            ret = Student.objects.get(pk=pk).delete()
    
            return Response(None,status=status.HTTP_204_NO_CONTENT)
    demo/views.py
    from django.db import models
    
    # Create your models here.
    class Student(models.Model):
        #以下模型字段默认时不能为空 null=False
        name = models.CharField(max_length=100,verbose_name="姓名")
        sex = models.BooleanField(default=1,verbose_name="性别")
        age = models.IntegerField(verbose_name="年龄")
        class_null = models.CharField(max_length=5,verbose_name="班级编号",null=True)
        description = models.TextField(max_length=1000,verbose_name="个性签名",null=True)
    
        class Meta:
            db_table="tb_student"
            verbose_name ="学生"
            verbose_name_plural = verbose_name
    demo/models.py
    from rest_framework import serializers
    
    from students.models import Student
    
    class StudentModelSerializer(serializers.ModelSerializer):
        class Meta:
            model= Student
            fields = "__all__"
    demo/serializers.py
    from django.urls import path, re_path
    from . import views
    urlpatterns = [
        path(r"students/",views.StudentsAPIView.as_view()),
        re_path(r"students/(?P<pk>d+)/",views.StudentAPIView.as_view()),
    ]
    demo/urls.py
    from django.contrib import admin
    from django.urls import path,include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path("stu/",include("students.urls"))
    ]
    urls.py

    分为两个类:

    查询所有、创建记录

    修改一条记录、删除一条记录、查询一条记录

  • 相关阅读:
    [转发]深入理解git,从研究git目录开始
    iOS系统网络抓包方法
    charles抓包工具
    iOS多线程中performSelector: 和dispatch_time的不同
    IOS Core Animation Advanced Techniques的学习笔记(五)
    IOS Core Animation Advanced Techniques的学习笔记(四)
    IOS Core Animation Advanced Techniques的学习笔记(三)
    IOS Core Animation Advanced Techniques的学习笔记(二)
    IOS Core Animation Advanced Techniques的学习笔记(一)
    VirtualBox复制CentOS后提示Device eth0 does not seem to be present的解决方法
  • 原文地址:https://www.cnblogs.com/linux985/p/11001813.html
Copyright © 2011-2022 走看看