首页 > 其他分享 >drf学习总览,http请求不同编码格式,请求体什么样子,新的Request对象和Response, 序列化类,反序列化保存

drf学习总览,http请求不同编码格式,请求体什么样子,新的Request对象和Response, 序列化类,反序列化保存

时间:2024-07-25 21:30:46浏览次数:5  
标签:序列化 请求 request instance 总览 data Response

Ⅰ drf学习总览概述

# 1 请求和响应
    request:请求对象:请求方式,请求携带的数据,request.GET,request.POST,requset.body,request.META:请求头中得
    四件套:操作响应体
        HTTPResponse('sdfs')  # 若是要携带请求头和响应状态码  应该是 return HTTPResponse('sdfs', status=201, headers={"xx":"yy"})
        JsonResponse(字典列表)
        render(request,模板文件)
        
    drf有自己的请求和响应
        request
        Response 的对象
            
# 2 序列化类:Serializer  用途
        1.做序列化
        2.做反序列化的
        3.反序列化的校验
        
# 3 视图类:drf提供了非常多 视图类可以继承
# 4 路由
# 5 认证:登录认证
# 6 权限
# 7 频率限制
# 9 统一返回错误
# 10 jwt:登录认证用
# 11 基于角色的访问控制

Ⅱ http请求不同编码格式,请求体什么样子

【一】get请求能不能再请求体中携带数据?

能
一般都是post或put请求在请求体中带数据

【二】get请求和post请求区别?

GET:主要用于获取服务器上的资源。GET请求通常用于查询数据,不应当引起服务器上的任何状态变化。
POST:主要用于向服务器发送要被处理的数据(例如,表单数据、文件上传等)。

GET:由于数据附加在URL中,因此GET请求的数据大小受到URL长度限制,通常限制在1024字节左右。
POST:数据包含在请求体中,理论上没有大小限制,可以发送大量数据。相对更安全

总结来说,GET请求更适合用于获取数据,而POST请求更适合用于发送数据

【三】总结

django视图类或视图函数的request
        request.POST:只针对于 post请求的urlencoded编码格式 才有数据 # 重点
        request.GET:请求地址栏中得参数:get,post,delete,put
        	# <QueryDict: {'key': ['key', '99']}>
            类字典:取出key的值
                只取一个:request.GET.get('key')
                两个都取:request.GET.getlist('key')
        request.body:无论什么请求, 无论什么编码格式,都在里面
        
http不同编码格式
    	urlencoded:在请求体中是  key=value&key=value
        json:在请求体中是  {"name":"lqz","age":19}
        form-data: asdfasdf-------数据部分  asdfasdfasdf-----文件部分
  • form-data请求体编码格式如下图

Ⅲ 新的Request对象和Response

【一】 Request

# 1  以后全是cbv,继承一个基类--> drf的APIView【也继承了Django的View】及子类
# 2 继承APIView后, 以后响应统一用 drf的响应  : Response

# !!!!!!!  如果想用 Response 要在 settings里面 将 rest_framework 放进去  否则会报错

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'app01.apps.App01Config',
    'rest_framework',
]

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.views import View
from rest_framework.request import Request


class BookView(APIView):
    def get(self, request):
        '''
        1 request 请求对象:http请求的所有内容,都会在这个对象中
        2 继承APIView后的request对象,不是之前的request对象了
             原来的:django.core.handlers.wsgi.WSGIRequest
             新的: rest_framework.request.Request
        3 用起来跟之前一样
            print(request.method)
            print(request.POST)
            print(request.GET)
            print(request.get_full_path())
        4 request.data
            无论那种编码格式,请求体的数据,都在这里面
                urlencoded,form-data:是QueryDict的对象
                json:是普通字典对象
                但是,都当字典用即可
        5 request.FILES
            前端传的文件从这里取
        6 request.query_params # 查询参数
            request.GET

        7 老的request在
            requset._request
        '''
        # print(type(request))
        # print(request.method)
        # print(request.POST)
        # print(request.GET)
        # print(request.get_full_path())

        print(request.data)
        print(request.query_params)
        print(request._request)

        # return JsonResponse({'code':100,'msg':'请求成功'})
        # 如果使用postman访问,返回json,如果使用浏览器访问,会返回好看的样式界面,使用Response必须注册app
        return Response('ok', status=status.HTTP_404_NOT_FOUND, headers={'xx': 'yy'})

【二】Response

from rest_framework.response import Response

【1】如何用

直接放字典,列表或字符串 
Response('ok')
    	放在响应体中了

【2】如何放状态码

Response('ok',status=201)

【3】如何放响应头

Response('ok',status=201,headers={'xx':'yy'})

【4】总结 Response

data=None # 响应体:可以传 字典,列表或字符串
status=None# http响应 状态码-->drf封装了所有常量   HTTP_200_OK = 200    从from rest_framework import status看    CTRL加鼠标右键  点击status看
template_name=None# 忽略掉-->指定使用浏览器访问返回的模板,没写用默认模板
headers=None # 响应头           
exception=False# 异常
content_type=None # 响应编码格式,一般不动,都用json
  • template_name=None
  • 在源码中看,最后是好看的模板样式
  • 如果使用postman访问,返回json,如果使用浏览器访问,会返回好看的样式界面

Ⅳ 序列化类

【一】序列化类介绍

# 序列化类的作用
	前端传json格式字符串 给 后端 -->后端需要 保存到数据库--->   这就需要反序列化
    后端从数据库查出来的 对象--->以json格式字符串的形式给前端-->  这就需要序列化
    
    serializer就是为了完成上面的操作
    	序列化
        反序列化
        反序列化校验

【二】快速使用

  • app下的models.py
from django.db import models


class Student(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    gender = models.IntegerField(choices=((1, '男'), (2, '女'), (0, '未知')))
  • 先进行路由分发
from django.urls import path,include

urlpatterns = [

    path('api/v1/', include('app01.urls')),
]
  • app下的路由urls.py
from .views import BookView,BookDetailView,StudentView,StudentDetailView
from django.urls import path


urlpatterns = [
    path('students/', StudentView.as_view()),
    path('students/<int:pk>/', StudentDetailView.as_view()),
]
  • app下的views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
import json
from django.http import JsonResponse, HttpResponse

from .serializer import StudentSerializer
from .models import Student

# 查询所有数据
class StudentView(APIView):
    def get(self,request):
        # 查出所有学生
        # 得到的是 queryset对象
        result = Student.objects.all()

        # 序列化
        # 第一种方法
        # 序列化 -->笨办法 -->自己拼接,麻烦一些
        # lli=[]
        # for student in result:
        #     lli.append({'id':student.pk,'name':student.name,'age':student.age,'gender':student.get_gender_display()})

        # 第二种
        # 2 drf提供的序列化类完成序列化:instance要序列化的对象,如果是多条 many=True
        serializer = StudentSerializer(instance=result, many=True)



        # 返回
        # return JsonResponse(result,safe=False)  # Object of type QuerySet is not JSON serializable
        # return Response(result)   # no such table: app01_student 这个报错是由于还没有迁移数据库
        # return Response(result)   # Object of type Student is not JSON serializable
        return Response(serializer.data)
    
    
# 查询单条数据
class StudentDetailView(APIView):
    def get(self, request, pk):
        # 1 根据id查出对象
        obj = Student.objects.filter(pk=pk).first()
        # 2 序列化
        serializer = StudentSerializer(instance=obj)
        # 3 返回
        return Response(serializer.data)

  • app下serializer.py
from rest_framework import serializers

'''
使用步骤:
    1 定义一个类,继承Serializer
    2 在类中写要序列化的字段:字段类,跟models中得一一对应
    3 在视图类中使用
'''

from .models import Student
class StudentSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    name = serializers.CharField(required=True)    # 不想在postman上展示那个字段 只需要注销即可
    age = serializers.IntegerField(required=True)
    gender = serializers.IntegerField(required=False,default=0)

【三】常用字段

#  记住-->跟models中得 model.字段类, 一一对应
#  具体有哪些-->了解
# 常用的一些字段 用# 标记出
BooleanField
NullBooleanField	
CharField  # 	
EmailField	
RegexField	
SlugField	
URLField	
UUIDField	
IPAddressField
IntegerField	  #  
FloatField
DecimalField	
DateTimeField  # 	
DateField	  #
TimeField	  #
ChoiceField	
MultipleChoiceField	
FileField	
ImageField	
# --------两个特殊的,很重要----
ListField
DictField	
#  大绝招:如果不知道models和Serializer如何对应
	序列化类统一用 CharField 

【四】 常用字段参数

#  序列化的 字段类在实例化时,传参数
	-作用是:为了反序列化校验用
    
#  有哪些字段参数-->了解
	# 只针对于:CharField
	max_length	最大长度
    min_lenght	最小长度
    allow_blank	是否允许为空
    trim_whitespace	是否截断空白字符
    
    # 只针对于:IntegerField
    max_value	最小值
    min_value	最大值
    
    # 只针对于:DateTimeField 
    format:序列化时,显示的格式
    DateTimeField(format='Y-m-d')
    或者  DateTimeField(format='Y/m/d')...
    # 所有字段类都用
    required:是否必填	
    default	:反序列化时使用的默认值
    allow_null	表明该字段是否允许传入None,默认False

    
#  两个重点
    read_only	表明该字段仅用于序列化输出,默认False
    write_only	表明该字段仅用于反序列化输入,默认False

Ⅴ 反序列化保存

【一】新增

#  使用步骤:
    1. 写个序列化类,继承Serializer
    2. 在序列化类中写字段,和字段参数[校验用的]
    3. 在视图类中使用
    	    def post(self, request):
        # 1 取出前端传入的数据-->无论什么编码格式,无论什么请求方式    request.data
        serializer = StudentSerializer(data=request.data)
        # 2 反序列化校验,保存到数据库
        if serializer.is_valid():
            # 校验通过,保存,会报错,    所以在序列化类中重写create方法
            serializer.save()
            # 3 返回给前端成功
            # return Response(serializer.data) # 把新增的数据,序列化一下,返回
            return Response({'code': 100, 'msg': '保存成功'})
        else:
            # 4 返回给前端失败
            return Response({'code': 101, 'msg': '数据校验失败'})
    4.要在序列化类中重写create
      def create(self, validated_data):
        # validated_data:前端传入,校验过后的数据
        student=Student.objects.create(**validated_data)
        return student # 不要忘了,返回新增的对象--->后期调用serializer.data 时,会使用它序列化

【二】修改

#  使用步骤:
    1. 写个序列化类,继承Serializer
    2. 在序列化类中写字段,和字段参数[校验用的]
    3. 在视图类中使用
    def put(self, request, pk):
        # 1 查出要修改的对象
        obj = Student.objects.filter(pk=pk).first()
        # 2 拿到前端传入的数据--修改成的数据
        serializer = StudentSerializer(instance=obj, data=request.data)
        # 3 校验数据是否合法
        if serializer.is_valid():
            # 4 修改   在序列化类中重写 update
            serializer.save()

            return Response({'code': 100, 'msg': '修改成功'})
        else:
            # 4 返回给前端失败
            return Response({'code': 101, 'msg': '修改失败,因为数据校验失败'})

    4.要在序列化类中重写update
      def update(self, instance, validated_data):
        # validated_data:前端传入,校验过后的数据
        # instance:待修改的对象
        # 1 笨办法
        # instance.name=validated_data.get('name')
        # instance.age=validated_data.get('age')
        # instance.gender=validated_data.get('gender')
        # 2 高级办法
        for key in validated_data: # 循环拿到字典的一个个key
            # 等同于 instance.name=validated_data.get('name')
            setattr(instance,key,validated_data.get(key))

        instance.save()
        return instance #不要忘了,返回修改的对象--->后期调用serializer.data 时,会使用它序列

【三】源码

# 1 为什么要重写 update和create
	因为执行serializer.save--->会触发self.create或self.update执行
    我们没写-->找父亲-->找父亲-->找到了
    def create(self, validated_data):
        raise NotImplementedError('`create()` must be implemented.')
# 2 为什么调用的都是save,但是最后触发的序列化类中得方法是不同的?
	因为内部判断了 instance 是否为None

# 阅读源码
	serializer.save()-->序列化类对象【自己写的StudentSerializer,没有save】 调用save,会触发父类的save-->Serializer中也没有save--->继续找父类BaseSerializer 有save方法
    save源码
    	# self 是咱们写的序列化类的对象
        # 如果是修改,instance 有值
        if self.instance is not None:
            # self.update 自己重写了,调用自己的
            self.instance = self.update(self.instance, validated_data)
        else:
            self.instance = self.create(validated_data)
        return self.instance

标签:序列化,请求,request,instance,总览,data,Response
From: https://www.cnblogs.com/zyb123/p/18324159

相关文章

  • pikachu 之CSRF(跨站请求伪造)get和post型
    CSRF(跨站请求伪造)概念跨站请求伪造(Cross-SiteRequestForgery,简称CSRF)是一种攻击方式,攻击者通过伪造用户的请求,欺骗受害者在不知情的情况下执行不想要的操作。这种攻击利用了用户已经在目标网站上通过身份验证的状态(如登录状态),从而以用户的身份发送恶意请求。工作原理......
  • Django DRF安装设置 序列化器ModelSerializer 视图ModelViewSet 路由url 串讲
    在DjangoRESTFramework(DRF)中,重新编写API视图通常涉及几个步骤。以下是一个简单的示例,展示如何定义和注册视图集、序列化器和路由,以便你可以创建、读取、更新和删除(CRUD)数据。1.定义序列化器#serializers.pyfromrest_frameworkimportserializersfrom.models......
  • 深入探索:使用Python进行网站数据加载逻辑分析与请求
    作为一名资深的Python程序员,我经常需要从网站中提取数据以供分析或进一步处理。这项任务涉及到对网站数据加载逻辑的深入分析,以及使用Python进行高效的网络请求。在本文中,我将分享如何分析网站的数据加载方式,并使用Python的requests库来模拟浏览器行为,获取所需的数据。网站......
  • 即使第一次发出请求,Pytends API 也会抛出 429 错误
    我正在使用非常简单的代码按区域查找关键字的数据。但每次我运行它时,它都会给我429错误,提示发出了太多请求,但实际上该请求是第一次发出,以前从未发出过。下面提到了我收到的错误。引发异常。TooManyRequestsError.from_response(response)pytrends.exceptions.TooManyRequ......
  • Python3打开图片时请求ConnectionResetError(10054)
    我试图从'http://xxx.jpg'之类的网站下载图片。代码:headers={'user-agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/66.0.3359.139Safari/537.36'}url='http://xxx.jpg'resp......
  • DRF入门规范,API接口,接口测试工具,restful规范,序列化和反序列化,drf安装和快速使用
    ⅠDRF入门规范【一】Web应用模式在开发Web应用中,有两种应用模式:【1】前后端不分离【2】前后端分离【3】前后端开发模式#1前后端混合开发-不少公司在用-flask混合-django混合-例如最简单的bbs项目-模板:dtl语法:djangotemplatelanguage模板语......
  • Django 序列化程序无法将查询集序列化为 JSON
    尝试简单的Django序列化器。我使用具有特定值的queryset然后我将queryset或queryset.values()传递给序列化器。为什么会出现500错误?@csrf_protectdefgeoLookup(request,**kwargs):country=kwargs.get('Country')city=kwargs.get('Place'......
  • 从 post 请求发送的回调中提取数据
    当我的服务余额更新时,然后向我的服务器http://.../callback发送请求,其中包含屏幕截图中的数据,并且从这些数据中,我需要将_id和SocialnetworkId提取到变量中,以便进一步添加到机器人数据库和交互(data.from.socialNetworkId和data.from._id)在此处输入图像描述......
  • Selenium 是否可以检测发送到 devtools 网络选项卡中站点的特定请求?
    我在Chrome和Firefox上使用python上的Selenium。我希望selenium等待,直到将特定请求发送到可以位于devtools的网络选项卡中的站点。例如名称为“index-24c3e2ca18.js”且请求URL为“https://www.wikipedia.org/portal/wikipedia.org/assets/js/index-24c3e2ca18.js”......
  • jackson序列化(jackson codec)
    Jackson是一个用于Java平台的开源JSON库,它提供了灵活且高效的方式来处理JSON数据的序列化(Java对象→JSON字符串)和反序列化(JSON字符串→Java对象)。以下是Jackson的一些主要特点和功能:高性能:Jackson通过使用基于流的处理模型和性能优化技术,提供了出色的性能。它支......