首页 > 编程语言 >学习python-Day64

学习python-Day64

时间:2022-09-26 19:33:23浏览次数:52  
标签:python self request 视图 学习 book Day64 序列化 data

回顾补充知识

  1. http请求

    • 应用层:基于tcp/ip之上

    • 是进行网络传输,广泛用于前后端的交互

    • 请求协议:

      • 请求首行

        请求方式 :get、post,请求地址:get携带数据,请求协议,请求版本:0.9/1.1/2.x

      • 请求头:key:value

      • 请求体

        post请求携带数据:三种编码格式

    • 响应协议

      • 响应首行

        响应协议版本,状态码,状态描述字符串

      • 响应头

        携带 cookie

      • 响应体

        浏览器里面可以看到的东西

        • html格式
        • json格式
  2. drf快速使用

    pip3 install djangorestframework

    所有接口:本质都是5个接口及其变型

  3. View执行流程,源码分析

    • cbv 都要继承View>>>路由写法变成>>>视图类.as_view() >>> 在视图类中写 get,post, delete

    • 路由:视图类.as_view() >>> 执行结果是个函数内存地址,请求来了,路由匹配成功,就会执行视图类.as_view()(request)

    • 视图函数(View)as_view类的绑定方法,本质路由就放了view函数的内存地址

    • 请求来了执行view(request) >>>本质又执行了 self.dispatch(request, *args, **kwargs)

    • 视图类找dispatch,Viewdispatch

    • 核心代码

       if request.method.lower() in self.http_method_names:
                  	# 反射:通过字符串去对象中找属性或方法
                      #handler就是TestView中的get方法
                      handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
              else:
                  handler = self.http_method_not_allowed
              return handler(request, *args, **kwargs) # get(request)
        
      
  4. restful规范----10条

    1. http:传输安全
    2. 地址中国带有api标识
    3. 地址中带有版本号
    4. 请求地址用名词,复数表示
    5. 通过请求方式区别获取资源的方式
    6. 响应状态码:http 自定义状态码
    7. 响应带有错误信息
    8. 请求带过滤条件
    9. 响应中带地址
    10. 返回数据符合条件如下规范:
      • 查所有 数组、列表
      • 查单个:对象
      • 删除:空白档
  5. http协议版本区别

    • 0.9:每个http请求都是一个tcp的链接
    • 1.1:keep-alive,多个http请求可以使用同一个tcp
    • 2.x:同一个tcp的包,可能是多个http请求,多路复用
  6. 你知道的http请求头有哪些?

今日学习内容

APIView基本使用

  • drf,是一个第三方的app,只能在django上使用
  • 安装drf后,导入一个视图类APIView,所有后期要使用drf写视图类,都是继承APIView及其子类

使用View + JsonResponse

class BookView(View):
    def get(self, request):
        print(type(request))
        book_list = Book.objects.all()
        # book_list是queryset对象不能直接序列化,只能通过for循环一个个拼成列表套字典的形式
        res_list = []
        for book in book_list:
            res_list.append({'name': book.name, 'price': book.price, 'publish': book.publish})
        return JsonResponse(res_list,safe=False,json_dumps_params={'ensure_ascii':False})  # 只能序列化字典和列表,

使用APIView + drf 的Response

  • 要先将rest_framework 注册settings.py到这个app

    这样才可以观察到好看的请求响应的信息

    image

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

class BookView(APIView):  # APIView继承自django的View
    def get(self, request):
        # print(type(self.request))  # 新的request
        # print(type(request))
        print(request._request)
        print(type(request._request)) #django.core.handlers.wsgi.WSGIRequest

        # print(request.method)  # get
        # print(request.path)  # /books/
        # print(request.GET)  # 原来的get请求提交的参数
        # print(request.POST)  # 原来post请求提交的参数

        book_list = Book.objects.all()
        # book_list是queryset对象不能直接序列化,只能通过for循环一个个拼成列表套字典的形式
        res_list = []
        for book in book_list:
            res_list.append({'name': book.name, 'price': book.price, 'publish': book.publish})
        return Response(res_list)

APIView源码分析

注意:视图类继承APIView后,执行流程就发生了变化,这个变化就是整个的drf的执行流程。

# 一旦继承了APIView入口
	-路由配置跟之前继承View是一样的----》找视图类的as_view---》【APIView的as_view】
        @classmethod
        def as_view(cls, **initkwargs):
            # 又调用了父类(View)的as_view
            view = super().as_view(**initkwargs)
            '''
            # 从此以后,所有的请求都没有csrf的校验了
            # 在函数上加装饰器
            @csrf_exempt
            def index(request):
                pass
            本质等同于 index=csrf_exempt(index)
            '''
            return csrf_exempt(view)
        
    -请求来了,路由匹配成功会执行 View类的的as_view类方法内的view闭包函数(但是没有了csrf认证),
    -真正的执行,执行self.dispatch---->APIView的dispatch  【这是重点】
     def dispatch(self, request, *args, **kwargs):
        # 参数的request是原来的django原生的request
        # 下面的request,变成了drf提供的Request类的对象---》return Request(。。。)
        request = self.initialize_request(request, *args, **kwargs)
        # self 是视图类的对象,视图类对象.request=request 新的request
        self.request = request
        try:
            # 执行了认证,频率,权限 [不读]
            self.initial(request, *args, **kwargs)
            # 原来的View的dispatch的东西
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                 self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            response = handler(request, *args, **kwargs)
        except Exception as exc:
            # 如果出了异常,捕获异常,处理异常,正常返回
            # 在执行三大认证和视图类中方法过程中,如果出了异常,是能被捕获并处理的---》全局异常的处理
            response = self.handle_exception(exc)
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

总结:

  1. 只要继承APIView都没有csrf分认证
  2. 以后视图类中使用的request对象,已经变成了drf提供的Request类的对象
  3. 执行视图类的方法之前,执行3大认证(认证,权限,频率)
  4. 在执行三大认证和视图类的方法过程中只要报错,都会被捕获处理

Request类源码分析

  • 视图中使用的request对象,已经变成了drf提供的request类的对象

    原生django 的request是这个类的对象:django.core.handlers.wsgi.WSGIRequest
    drf 的request是这个类的对象:rest_framework.request.Request
    
  • request已经不是原来的request了,但是还是可以像原来那样使用

    print(request.method)  # get
    print(request.path)  # /books/
    print(request.GET)   # 原来的get请求提交的参数
    print(request.POST)  # 原来post请求提交的参数        
    
  • Resquest的源码分析:res_framework.request.Request

    '类中有个魔法方法:__getattr__    对象.属性,属性不存在会触发它的执行'
    
    def __getattr__(self, attr): # 如果取的属性不存在会去原生django的request对象中取出来
            try:
                #反射:根据字符串获取属性或方法,self._request 是原来的request
                return getattr(self._request, attr)
            except AttributeError:
                return self.__getattribute__(attr)
            
    

    总结

    1.以后用的所有的属性或方法,直接用点的方式就行。(通过反射去原来request中取)
    2.新的request内部有个老的request,就是request._request
    3.data 是个方法,被property装饰了,变成了数据属性用
    	request.POST 可以获取body体提交的数据
        request.POST 可以获取urlencoded,form-data 提交的数据
        json 格式提交的数据,在request.POST中找不到,应该在request.body中找
        现在无论哪种格式,都从request.data中取
     
    4.query_params:get请求提交的参数,等同于request._request.GET 或 request.GET
      
    5.取文件也是从request.FILES中取
     
    6.
    原生requets.POST 只能获取urlencoded和form-data格式提交的数据,json格式提交的数据在body中,拿出来自己处理,但是drf的request中有个 data , data 中可以取到任意编码提交的数据。
    
    7. request.data  
    有时候结果是(urlencoded,form-data)QueryDict,有时候(json)是字典。
    
    
  • 什么是魔法方法?

    1 在类中只要以__开头,__结尾的都称之为魔法方法
    2 这种方法不需要手动调用,某种情况会自动触发
    3 你学过的: __init__,__str__,__call__,......
    

序列化组件介绍

drf提供了一种可以快速实现序列化的类:序列化类

序列化组件基本使用

定义一个序列化类

写序列化类:给book进行序列化
# from rest_framework.serializers import Serializer
from rest_framework import serializers


class BookSerializer(serializers.Serializer):
    # 要序列化的字段    有很多字段类,字段类有很多字段属性
    name = serializers.CharField()  # 字段类
    # price = serializers.CharField()
    publish = serializers.CharField()

使用序列化类,序列化多条数据

class BookView(APIView):  # APIView继承自django的View
    def get(self, request):
        book_list = Book.objects.all()
        # instance表示要序列化的数据,many=True表示序列化多条(instance是qs对象,一定要传many=True)
        ser = BookSerializer(instance=book_list, many=True)

        return Response(ser.data)

使用序列化类,序列化单挑数据

class BookDetailView(APIView):
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book)
        return Response(ser.data)

反序列化(新增,修改)

新增,修改>>>前端传入的数据,要校验>>>序列化类有数据校验功能

新增

视图类

class BookView(APIView):  # APIView继承自django的View
    def post(self, request):
        # 前端传递数据,从request.data取出来
        ser = BookSerializer(data=request.data)
        if ser.is_valid():  # 表示校验前端传入的数据   没有写校验规则,现在等于没校验
            ser.save()  # 再写东西,这里会报错  调用save会触发BookSerializer的save方法,判断了,如果instance有值执行update,没有值执行create
            return Response(ser.data)
        else:
            return Response(ser.errors)

序列化类

class BookSerializer(serializers.Serializer):
    # 要序列化的字段    有很多字段类,字段类有很多字段属性
    name = serializers.CharField()  # 字段类
    price = serializers.CharField()
    publish = serializers.CharField()

    # 重写create方法,
    def create(self, validated_data):
        res = Book.objects.create(**validated_data)
        return res

修改

视图类

class BookDetailView(APIView):
    def put(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        # 前端传递数据,从request.data取出来
        ser = BookSerializer(instance=book, data=request.data)
        if ser.is_valid():  # 表示校验前端传入的数据   没有写校验规则,现在等于没校验
            ser.save()  # 再写东西,这里会报错  调用save会触发BookSerializer的save方法,判断了,如果instance有值执行update,没有值执行create
            return Response(ser.data)
        else:
            return Response(ser.errors)

序列化类

class BookSerializer(serializers.Serializer):
    # 要序列化的字段    有很多字段类,字段类有很多字段属性
    name = serializers.CharField()  # 字段类
    price = serializers.CharField()
    publish = serializers.CharField()

    # 重写update
    def update(self, instance, validated_data):
        # instance要修改的对象
        # validated_data 校验过后的数据
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.publish = validated_data.get('publish')
        instance.save()
        return instance

标签:python,self,request,视图,学习,book,Day64,序列化,data
From: https://www.cnblogs.com/bjyxxc/p/16731620.html

相关文章

  • python语法和运算符
    今日内容总结基础数据类型基本数据类型之布尔值bool什么是布尔值用来判断事物的对错是否可行只要用于流程控制中的逻辑判断布尔值的状态只有两种状态 1.True 对的......
  • 不带行交换的Guass消去法,python实现
    importnumpyasnp#合并A、b,增广矩阵ABclassgauss:def__init__(self,A:list,b_T:list):''':paramA:矩阵A,n*n:paramb_......
  • Python数据类型+运算符
    Python基础数据类型上期练习讲解#练习一.想办法打印出jasonl1=[11,22,'kevin',['tony','jerry',[123,456,'jason']]]#解题思路,先看列表中有几个数......
  • Python采集《惊奇先生》, 下载你想看的高质量漫画
    前言大家早好、午好、晚好吖~知识点:爬虫基本流程保存海量漫画数据requests的使用base64解码开发环境:版本:python3.8编辑器:pycharmrequests:......
  • Flask学习笔记(三)-jinja2 模板入门
    一、表达式jinja2是一个被广泛使用的模板引擎,其设计思想源自于django模板引擎,jinja2扩展了语法,增加了强大的功能,被flask选为内置的模板语言示例的目录结构如下./├─......
  • python进阶之路4
    内容回顾PEP8规范代码编写规范及美观python注释语法平时养成写注释的习惯 1.警号 2.三个单引号 3.三个双引号常量与变量1.变量语法结构 变量名......
  • 网络流入门学习笔记
    基本概念网络流,即网络+流网络就是由许多结点和边组成的图,在这里边权表示允许通过的最大流量在网络中,有两个特殊的结点,一个叫源点,一个叫汇点网络流中最大流问题可以看成......
  • python -day4
    python-day4目录python-day4python作业讲解基本数据类型布尔值bool基本数据类型元组tuple基本数据类型集合set用户交互格式化输出基本运算符常用赋值符逻辑运算符成员运......
  • [学习笔记]Kruskal以及Kruskal重构树
    1.\(\operatorname{Kruskal}\)最小生成树本来觉得这个没必要写但是强迫症发作只能写了qwq真实原因是我居然交了四发才过板子题可以说是人类之耻了\(\operatorname{Kru......
  • python练习题
    1.输入账号密码,判断成功,程序退出。判断失败,继续登录输入。考察点:while和if语句的运用,及flage标志位。#coding=utf-8;flage=True;whileflage:user=raw_inpu......