首页 > 其他分享 >drf中-序列化组件

drf中-序列化组件

时间:2023-02-01 20:14:23浏览次数:40  
标签:return self request drf 组件 序列化 data view

基于APIView+Response 写接口

在views.py中
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book


class BookView(APIView): # 使用cbv方法编写 继承APIView
    def get(self,request):
       book_list = []
       books = Book.objects.all() # 拿到所有数据对象
       for book in books:
          book_list.append({'name':book.name,'price':book.price})
       # 把数据对象转为字典 添加入一个列表
       return Response(book_list)
       # 使用drf内Response模块,可以直接将字典或列表序列化

分析APIView执行流程

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

path('books/', views.BookView.as_view())

1.APIView的as_view方法执行:view还是原来的view,但是去掉了csrf的认证
当请求来了的时候会执行views.BookView.as_view()这个方法,因为BookView类本身没有as_view()方法,所以从父类里面查找,查到了APIView里面的as_view方法并执行了
 	@classmethod
  # 类方法 调用父类的as_view
   def as_view(cls, **initkwargs):
        view = super().as_view(**initkwargs)
        # super是从父类中拿as_view(**initkwargs)方法并执行
        # 执行后获得了原生django中as_view中闭包函数view拿出来了
        return csrf_exempt(view)
        # csrf_exempt 排除所有请求的csrf认证
        # 最后相当于把原生view排除了所有csrf认证
        
2.路由匹配成功相当于执行了 csrf_exempt(view)(request),本质还是原生的view执行了self.dispatch
self是视图类对象(bookview对象由于bookview对象中没有dispatch方法,所以就从父类中找 APIView中找到了dispatch方法

    def dispatch(self, request, *args, **kwargs):
        request = self.initialize_request(request, *args, **kwargs)
        # 在这里把原来的request包装成了新的request 
        # 通过initialize_request方法看到把老的request放入了request._request中
        self.request = request
        # 把新的request放到了视图类的对象中
        try:
        # 开启异常捕获
            self.initial(request, *args, **kwargs)
            # 执行三大认证 认证 频率 权限

            if request.method.lower() in self.http_method_names:
              # 判断请求方式 是否在 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.先去除了所有请求的csrf认证
     2.包装了新的request 以后视图类中的request是新的了老的request在
     新的request._request里面
     3.在执行视图类方法之前 先进行了3大认证
     4.如果在执行3大认证或执行过程中出错 会有异常捕获

request源码分析

from rest_framework.request import Request

新的request中包含了老的  request._request就是老的

Request源码中:
        def __getattr__(self, attr):
        # __getattr__魔法方法:对象.属性如果该属性不存在则触发
        # request.get由于新的request中没有.method方法所以会触发这个魔法方法
        try:
            return getattr(self._request, attr)
            # 当这个方法被触发 就返回了老的request中的该方法
        except AttributeError:
            return self.__getattribute__(attr)
          
          
1.新的request用起来跟老的一样,是因为新的方法取不到就会默认取老的request的方法、
2.以后不管是什么数据,都从request.data中取,取出来就是字典
3.rul中携带的参数get请求携带的参数,以后从request.query_params中取
4.文件还是从request.FILES中取

class BookView(APIView):
    def get(self, request):
        print(self.request.data)
        print(self.request.query_params)
        print(self.request.FILES)

序列化组件(查询)

查询所有接口

首先创建序列化类

新建serializer.py文件:
from rest_framework import serializers
# 需要导入这个类 继承这个类
class BookSerializer(serializers.Serializer):
    name = serializers.CharField()
    # 写法导致跟models类相同
    price = serializers.CharField()
    publish = serializers.CharField()
    # 需要序列化的字段数据,这里写什么就会自动序列化什么,如果有表中不想展示的字段,
    # 这里可以不写那个字段


path('books/', views.BookView.as_view()),
    
views.py中
    创建类方法 get请求获取所有数据
    class BookView(APIView):
    def get(self, request):
        books = Book.objects.all()
        # 获得所有数据对象 queryset列表
        ser = BookSerializer(instance=books, many=True)
        # 把数据对象列表交给我们创建的序列化类进行处理,instance=需要序列化的数据
        # many=是否是多个数据,如果是单个数据对象不需要many属性
        return Response(ser.data)  
        # 直接把序列化好的数据返回,序列化好的数据在ser.data中

查询单个数据接口

查询单个url需要携带参数

 path('books/<int:id>', views.BookOneView.as_view()),

views.py中
 class BookOneView(APIView):
    def get(self, request, id):
        book = Book.objects.filter(pk=id).first()
        ser = BookSerializer(instance=book)
        # 由于book是单个数据 不需要many属性设置 默认many=False
        return Response(ser.data)

反序列化组件(新增/修改)

新增 
序列化文件中serializer.py中
添加类方法

path('books/', views.BookView.as_view()),

class BookSerializer(serializers.Serializer):
    name = serializers.CharField()
    price = serializers.CharField()
    publish = serializers.CharField()

    def create(self, validated_data):
        book_obj = Book.objects.create(**validated_data)
        return book_obj
     # 创建create方法 并返回创建的对象
    
    
views.py视图类中添加post请求方法    
 class BookView(APIView):
    def post(self,request):
        ser = BookSerializer(data=request.data)
        # 将序列化类中的数据改为request.data
        # request.data就是通过校验前端传来的数据
        if ser.is_valid():
          # 当数据通过校验 直接保存
            ser.save()
            # 执行.save方法 该方法中会调用对象本身的create方法
            # 我们通过序列化类产生了一个对象,然后用这个对象调用create方法
            # 就是调用了序列化类里面的create方法我们刚刚写的
            return Response({'code':100,'msg':'新增成功'})
        else:
            return Response({'code':101,'msg':ser.errors})

          
修改:
 path('books/<int:id>', views.BookOneView.as_view()),
  
 
views.py视图类中添加put请求方法    
class BookOneView(APIView):
    def put(self,request,id):
        book = Book.objects.filter(pk=id).first()
        # 拿到数据对象
        ser = BookSerializer(instance=book,data=request.data)
        # 数据对象传入序列化类中,instance=需要修改的数据 data=前端传过来的数据
        # 产生一个新的数据对象
        if ser.is_valid():
            ser.save()
            # 执行.save()方法,其中通过判断是否有instance属性来判断是执行 create
            # 还是执行updata 有执行了updata
            return Response({'code':100,'msg':'修改成功'})
        else:
            return Response({'code':101,'msg':ser.errors})

          
在序列化类中添加 updata方法:
			  def update(self, instance, validated_data):
        # instance=需要修改的对象 我们之前传的book
        # validated_data 前端的数据
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.publish = validated_data.get('publish')
        instance.save()
        # 更改过后对象进行保存
        return instance
        # 记得然后在返回出去
        

删除资源

不涉及序列化或反序列化

class BookOneView(APIView):
    def delete(self,request,id):
        res = Book.objects.filter(pk=id).first()
        if not res:
            return Response({'code': 103, 'msg': '该文件不存在'})
        res = Book.objects.filter(pk=id).first().delete()
        if res:
            return Response({'code':102,'msg':'删除成功'})

反序列化的校验

反序列就是 新增 和 修改 等写入数据库的动作

在序列化的类中添加钩子函数做校验

主动抛异常需要导入函数 
from rest_framework.validators import ValidationError


class BookSerializer(serializers.Serializer):
    # 序列化某些字段,这里写要序列化的字典
    name = serializers.CharField()  # serializers下大致跟models下的类是对应的
    price = serializers.CharField()
    publish = serializers.CharField()

		# 局部钩子 name字段
    def validate_name(self, name):
        if len(name) < 3:
          # 对name字段做限制
            raise ValidationError('书名须大于3位数')
            # 主动抛异常
        else:
            return name
          # 没有问题还把这个字段反出去
          
    # 全局钩子
    def validate(self, attrs):
        if attrs.get('name') == attrs.get('publish'):
            raise ValidationError('书名和出版社名称不能一致')
        else:
            return attrs
          
    总结:如果有问题就主动抛异常
         如果没有问题还把数据返回出去

标签:return,self,request,drf,组件,序列化,data,view
From: https://www.cnblogs.com/moongodnnn/p/17084016.html

相关文章

  • ApiView/Request类源码分析/序列化器
    内容概要ApiView+JsonResponse编写接口ApiView+Response编写接口ApiView源码解析Request对象源码分析序列化器介绍和快速使用/反序列化反序列化的校验ApiView+Jso......
  • APIView+Request源码分析,序列化器的使用,反序列化的校验
    APIView和Response初见APIView类是drf提供给咱们的一个类,以后使用drf写视图类,都是继承这个类及其子类。APIView本身就是继承了Django原生的View基于APIView+JsonResp......
  • drf day03 ApiView、Request、结合Response、反序列化组件编写5个接口
    一、APIView执行流程(较难)1.前戏​ 这个是drf提供的,以后我们写视图中的类都继承这个apiview​ rest_framework很规范,需要导啥先点一下,然后后面就可以按开头大写导导入一......
  • drf整体内容,APIView执行流程,Request对象源码分析,序列化器介绍和快速使用,反序列化,基于
    目录drf整体内容APIView执行流程(难,了解)基于APIView+JsonResponse编写接口基于APIView+Response写接口APIView的执行流程Request对象源码分析(难,了解)序列化器介绍和快速使......
  • django框架之drf:3、API执行流程、Response源码剖析、序列化器的简介和使用、反序列化
    Django框架之drf目录Django框架之drf一、APIView执行流程1、API执行流程总结(重点)2、补充二、Response源码剖析1、Response类总结(重点)三、序列化器的介绍和使用1、序列化......
  • drf
    今日内容概要1.APIView执行流程2.Request对象源码分析3.序列化器快速使用4.反序列化5.反序列化校验1.APIView执行流程基于APIView+JsonResponse编写接口原来基于dj......
  • 小程序的button组件
    button组件按钮组件功能比html的button按钮丰富可以通过open-type属性可以调用微信提供的各种功能(客服,转发,获取用户权限,获取用户信息等);按钮的属性siz......
  • DRF之APIView
    目录APIView执行流程基于APIView+JsonResponse编写接口基于APIView+Response写接口APIView的执行流程Request对象源码分析序列化器介绍和快速使用序列化类基本使用,序列化多......
  • React的受控组件与非受控组件
    收集表单数据受控组件在HTML中,表单元素(如input、textarea和select)通常自己维护state,并根据用户输入进行更新。而在React中,可变状态(mutablestate)通常保存在组件......
  • json .net 反序列化
    引用链接https://www.cnblogs.com/nice0e3/p/15294585.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%94%BB%E5%87%BBhttps://www.anquanke.com/post/id/172920#h3-3j......