【Django学习】(十一)APIView_请求与响应_GenericAPIView

news2024/11/16 10:21:41
  •  继承DRF中APIView之后,那么当前视图就具备了认证、授权、限流等功能
  •  继承DRF中APIView之后,每一个实例方法中的request为Request对象
  •  Request类拓展了Django中的HttpRequest类,具备很多额外优秀的功能
  • Request类与HttpRequest类中的所有功能兼容
  • 查询字符串参数:request.GET、request.query_param推荐
  • 获取json格式参数:request.body(还需要decode解码)、request.data(直接获取到字典)
  • 获取www-form参数:request.POST、request.data
  • 获取multipart/form-data:request.body、request.POST、request.data

一、APIView

1、Request_解析类

from rest_framework.views import APIView

 视图集中引用APIView

class ProjectsDetailViews(APIView):
.
.
.

class ProjectsViews(APIView):
    # 创建数据
    def post(self, request):
        ret = {
            "msg": "传参异常",
            "code": 404
        }
        # json_str = request.body.decode('utf-8')
        # try:
        #     data_dict = json.loads(json_str)
        # 如果入参不是json格式数据,抛出异常
        # except json.JSONDecodeError:
        #     return JsonResponse(ret, json_dumps_params={"ensure_ascii": False}, status=404)
        # 反序列化输入
        # serializer_obj = ProjectModelSerializer(data=data_dict)
        serializer_obj = ProjectModelSerializer(data=request.data)
        if not serializer_obj.is_valid(raise_exception=True):
            ret.update(serializer_obj.errors)
            return JsonResponse(ret, json_dumps_params={"ensure_ascii": False}, status=404)
        serializer_obj.save()

        return JsonResponse(serializer_obj.data, json_dumps_params={"ensure_ascii": False}, status=200)
  •  上面的代码中注释掉入参为json格式数据的处理,使用drf框架中自带的解析类
    • JSONParser:解析JSON请求内容。
    • FormParser:解析 HTML 表单内容
    • MultiPartParser:解析多部分HTML表单内容,支持文件上传

 设置解析器:

可以使用DEFAULT_PARSER_CLASSES设置全局默认的解析器集。例如,以下设置将仅允许具有JSON内容的请求,而不是JSON或表单数据的默认值。

  • 定义解析器类,用于解析不通的前端参数类型
  • 会自动根据请求头中Content-Type来解析参数
  • 无论前端传递这三种参数中的哪一种参数,都可以使用request.data去获取

 本项目中的配置文件添加配置:

 

 发起post请求:

 

 如果发起的数据请求格式在解析类中没有定义,则发起请求时返回提示请求格式不支持

 

 

    # 创建数据
    def post(self, request):
        ret = {
            "msg": "传参异常",
            "code": 404
        }
        # json_str = request.body.decode('utf-8')
        # try:
        #     data_dict = json.loads(json_str)
        # 如果入参不是json格式数据,抛出异常
        # except json.JSONDecodeError:
        #     return JsonResponse(ret, json_dumps_params={"ensure_ascii": False}, status=404)
        # 反序列化输入
        # serializer_obj = ProjectModelSerializer(data=data_dict)
        serializer_obj = ProjectModelSerializer(data=request.data)
        if not serializer_obj.is_valid(raise_exception=True):
            ret.update(serializer_obj.errors)
            return JsonResponse(ret, json_dumps_params={"ensure_ascii": False}, status=404)
        serializer_obj.save()

        return JsonResponse(serializer_obj.data, json_dumps_params={"ensure_ascii": False}, status=200)

 指定了解析类后,我们在视图集里就可以不用再手动处理json格式或者其他格式的入参(代码被注释掉的部分) ,drf内部会自动帮我们处理

 

2、Response_渲染类

  • 定义渲染类,用于返回不同类型的数据
    • 会自动根据请求头中Accept进行渲染
    • 如果前端不指定Accept,那么默认返回json格式的数据
    • 如果指定Accept为application/json,那么也会以json数据返回
    • 如果指定Accept为text/html(浏览器发起GET请求会自动指定),那么会以html形式返回
  • 在DRF的视图中,一定要以Response返回 
  • Response类为HttpResponse的子类,具备HttpResponse中的所有功能
  • 可以自动根据请求头中的Accept参数,来返回相应数据格式到前端
  • 第一个参数为Python中的常用数据类型(字典、嵌套字典的列表),尽量使用序列化器类.data
  • status指定响应状态码,content_type指定响应体数据类型
  •  

settings.py配置文件 

 

 指定了渲染类后,我们在views.py视图集里也可以不用再手动处理json格式的出参了,drf会内部自动帮我们处理并返回,所以可以不使用JsonResponse进行返回了。

# return JsonResponse(serializer_obj.data, json_dumps_params={"ensure_ascii": False}, status=200)

 可以使用Response进行返回:

return Response(serializer_obj.data,status=status.HTTP_201_CREATED)

 

二、GenericAPIView

  • GenericAPIView是APIView的子类,具备APIView的所有功能
  • 往往需要指定queryset和serializer_class两个类属性
  • queryset指定当前类视图需要使用的查询集
  • serializer_class指定当前类视图需要使用的序列化器类 

 

import ast
import json

from django.http import HttpResponse, JsonResponse, Http404
from rest_framework.response import Response
from rest_framework import status
from django.views import View
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from .models import ProjectsModel
from django.db import connection
from .serializers import ProjectSerializer, ProjectModelSerializer, ProjectNameSerializer

# 能够动态的查询生成的sql语句
connection.queries


# Create your views here.


# class ProjectsDetailViews(APIView):
class ProjectsDetailViews(GenericAPIView):
    queryset = ProjectsModel.objects.all()
    serializer_class = ProjectModelSerializer

    def get(self, request, pk):
        pro = self.get_object()
        serializer_obj = self.serializer_class(instance=pro)
        return Response(serializer_obj.data, status=status.HTTP_200_OK)

    # 更新数据
    def put(self, request, pk):

        # 查出对应id的数据
        query_data = self.get_object()
        serializer_obj = self.serializer_class(instance=query_data, data=request.data)
        serializer_obj.is_valid()
        # 保存更新的数据
        serializer_obj.save()
        return Response(serializer_obj.data, status=status.HTTP_201_CREATED)

    # 删除数据
    def delete(self, request, pk):
        ret = {
            "msg": "删除成功!"
        }
        # 根据id查出对应数据
        query_data = self.get_object()
        # 删除指定数据
        query_data.delete()
        # 一般删除数据的输出为None
        return Response(ret,status=status.HTTP_204_NO_CONTENT)


# class ProjectsViews(APIView):
class ProjectsViews(GenericAPIView):
    queryset = ProjectsModel.objects.all()
    serializer_class = ProjectNameSerializer

    # 查询全部数据
    def get(self, request):
        # 往往不要直接使用queryset类属性,去获取查询集对象
        # 一般需要使用self.get_queryset(),去获取查询集对象,因为更加灵活,后续可以重写父类的get_queryset()
        pro_data = self.get_queryset()
        serializer_obj = self.get_serializer(instance=pro_data, many=True)
        return Response(serializer_obj.data, status=status.HTTP_200_OK)

    # 创建数据
    def post(self, request):

        serializer_obj = self.get_serializer(data=request.data)
        serializer_obj.is_valid(raise_exception=True)
        serializer_obj.save()
        return Response(serializer_obj.data, status=status.HTTP_201_CREATED)

 说明:

  1. 在上面代码中,代用父类的get_object()方法,不用再传递pk值,因为get_object()内部已经实现了处理查询集,lookup_field提取出所需要得pk值
  2. 在调用序列化器类传递data时,使用request.data获取到入参数据(继承APIView中的解析器)
  3. 在ProjectViews类方法中(get\post),往往不要直接使用queryset类属性,去获取查询集对象
    1. 一般需要使用self.get_queryset(),去获取查询集对象,因为更加灵活,后续可以重写父类的get_queryset()
    2. 调用self.get_serializer,获取序列化器类对象,原因同理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/728820.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022年06月份青少年软件编程Scratch图形化等级考试试卷二级真题(含答案)

2022-06 Scratch真题二级 分数:100 题数:37 一、单选题(共25题,共50分) 1.角色初始位置如图所示,下面哪个选项能让角色移到舞台的左下角?( )(2分) A. B. C. D. 2.点击绿旗,执…

【面试题27】Redis中的connect和pconnect如何使用,有什么区别

文章目录 一、背景二、connect函数三、pconnect函数四、区别和使用场景五、总结 一、背景 本文已收录于PHP全栈系列专栏:PHP面试专区。 计划将全覆盖PHP开发领域所有的面试题,对标资深工程师/架构师序列,欢迎大家提前关注锁定。 Redis是一个开…

六、HAL_Timer的PWM功能

1、开发环境 (1)Keil MDK: V5.38.0.0 (2)STM32CubeMX: V6.8.1 (3)MCU: STM32F407XGT6 2、PWM简介 2.1、什么是PWM (1)PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。 (2)P…

Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling

感想:由于看不懂官方代码的原因,自己这方面耽误了一段时间,一方面,在AI与经济学之间犹豫了许久,另一方面,工作 了半年,也没发工资,没空找培训代码的课程,所以停止更新了三…

Nginx-代理服务器详解

本文已收录于专栏 《中间件合集》 目录 概念说明Nginx代理 提供服务总结提升 概念说明 Nginx Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。它具有很多非常优越的特性:在连接高并发的情况下,Nginx是Aoache服…

机器学习算法之决策树(decision tree)

1 决策树算法介绍 决策树(Decision Tree,又称为判定树)算法是机器学习中常见的一类算法,是一种以树结构形式表达的预测分析模型。决策树属于监督学习(Supervised learning),根据处理数据类型的不同,决策树又为分类决策…

html 模板

模板王 - 10000免费网页模板,网站模板下载大全 (mobanwang.com)http://www.mobanwang.com/

C++ string中内置的字符串操作和标准库中常用字符处理函数

💯 博客内容:C读取一行内个数不定的整数的方式 😀 作  者:陈大大陈 🚀 个人简介:一个正在努力学技术的准前端,专注基础和实战分享 ,欢迎私信! 💖 欢迎大家&…

Qt之QDialog 自定义标题栏

简述 Qt自带标题栏功能还是很强大的,但是确实不能百分百满足需求,除了丑以外还不能随意更改标题栏字体,也不能更改样式;所以为了满足自己的虚荣心让标题栏变得更加好用看好看,特地花时间做了以下测试; 支持…

SpringBoot通过获取请求参数或者Headers上的特殊标识实现i18n国际化

实现效果 我们大部分都是把i18n的标识放在Headers上面;而把标识放在参数上的话比较少,放参数上的话一般是在使用a标签下载某些文件不好配置请求头的时候才使用上 配置在Headers上面: 配置在params上面: 配置代码: /**…

Django_类视图(五)

目录 类视图优点 使用方法 定义类视图 添加类视图路由 类视图原理 类视图的二次封装 类视图二次封装代码如下 编写视图 配置路由 访问url结果 源码等资料获取方法 类视图优点 使用django的函数视图,如果要让同一个视图实现不同的请求方式实现不同的逻辑…

Android Studio实现内容丰富的安卓社交论坛平台

如需源码可以添加q-------3290510686,也有演示视频演示具体功能,源码不免费,尊重创作,尊重劳动。 项目编号085 1.开发环境 android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端: 1.注册登录 2.查看公告 3.视…

静态路由介绍

目录 静态路由配置方法(基本配置): 静态路由的拓展配置 负载均衡 1.环回接口——测试 2.手工汇总——子网汇总 3.路由黑洞(黑洞路由) 4.缺省路由 5.空接口——NULL 0 静态路由配置方法(基本配置)&#xff1…

【Linux】Linux下的项目自动化构建工具——make和makefile

❤️前言 大家好,好久不见!今天小狮子为大家带来的文章是一篇关于Linux下的项目自动化构建工具——make和makefile的博客,希望能帮助到大家。 正文 当我们进行涉及多文件的工程开发时,我们需要对很多不同类型、不同功能&#xff…

如何查看论文被引用情况

Dimensions上汇聚了多种类型的学术成果(期刊、图书、专利、临床试验),它好的地方在于可将论文与被引用情况、研究资金来源、相关临床试验、专利信息以及政策文件全部关联起来,从而对一项研究进行了从起源到结果的全方位描述。 网…

第九十九天学习记录:C++核心:类和对象Ⅴ(五星重要)友元运算符重载

友元 在程序里&#xff0c;有些私有属性也能让类外特殊的一些函数或者类进行访问&#xff0c;就需要用到友元的技术 友元的目的就是让一个函数或者类访问另一个类中私有成员 友元的关键字为frirend 友元的三种实现 1、全局函数做友元 #include<iostream> using namespa…

vue 使用百度地图记录

参考文档 https://lbsyun.baidu.com/index.php?titlejspopular3.0/guide/infowindow https://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference_3_0.html#a0b0 1.百度地图标注点点击出现infoWindow信息窗口添加点击事件 var opts {width: 200, // 信息窗口宽度height:…

【TS】学习笔记

1、所有的JavaScript代码都是有效的Typescript代码&#xff0c;用TypeScript编译器编译TypeScript里的Javascript代码&#xff0c;编译后的结果与原始的Javascript代码一模一样&#xff0c;即文件扩展名从.js改为.ts&#xff0c;不会造成任何负面的影响 2、JavaScript代码迁移…

idea将代码片段提取成一个方法快捷方式

CtrlAltM 今天写代码发现有的方法太长了&#xff0c;为了使我们的代码更加简洁&#xff0c;就可以使用idea的这个功能 效果如图 改造前&#xff1a; 提取出两个方法 如何使用

Bootloader Design of PIC18 series MCU - 进阶篇

1.遭遇到问题 在&#xff1a;PIC18 Bootloader 设计基础 一文中&#xff0c;我们讨论了Bootloader与上层应用APP各自编译的方法。在ROM上的空间分配、以及跳转、中断的处理等内容。那篇文章包含了所有与PIC单片机Bootloader设计相关的技术问题。但是距离一个真正可用的Bootloa…