DRF的接口使用

【一】如何看cbv源码

​ 需要看源码。 在看python源码的时候 一定要时刻提醒自己面向对象属性方法查找顺序

  • 先从对象自己找
  • 再去产生对象的类里面找
  • 之后再去父类找

总结: 看源码只要看到了self点一个东西 一定要问你自己当前这个self到底是谁

cbv的源码 : 突破口在urls.py

from django.contrib import admin
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    # CBV源码
    re_path('r^login/',views.MyLogin.as_view()),
]
# re_path('r^login/',views.view),  这里CBV跟FBV 一模一样
# '''这里可以看出CBV跟FBV在路由匹配上本质是一样的 都是路由 对应 函数内存地址'''

# 函数名/方法名  加括号优先级最高
# 这里我们可以假设一下
	as_view()
    	要么是被@staticmethod修饰的静态方法
        要么是被@classmethod修饰的类的方法  ✓
        
	@classonlymethod
    def as_view(cls, **initkwargs):
        """Main entry point for a request-response process."""
        for key in initkwargs:
            pass
# cls 就是我们自己写的类  MyCBV
def view(request, *args, **kwargs):
    # cls 就是我们自己写的类
    # self = MyLogin(**initkwargs)  产生一个我们自己写的类的对象
    self = cls(**initkwargs)
    self.setup(request, *args, **kwargs)
'''
		需要看源码。 在看python源码的时候  一定要时刻提醒自己面向对象属性方法查找顺序

		- 先从对象自己找
		- 再去产生对象的类里面找
		- 之后再去父类找

总结: 看源码只要看到了self点一个东西  一定要问你自己当前这个self到底是谁
'''
# CBV的精华
def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    
    # 获取的当前请求的小写格式  如何对比当前请求方式是否合法
    # get请求为例子
    # post请求
    if request.method.lower() in self.http_method_names:
        handler = getattr(
            self, request.method.lower(), self.http_method_not_allowed
        )
        '''
        反射:通过字符串来操作对象的数学或者方法
        handler = getattr(自己写的类产生的对象,'get',当找不到get数学或者方法的时候机会用到第三个参数)
        handler = 我们自己写的类里面的get方法
        '''
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)

'''自动调用get方法'''

1

在这里插入图片描述

2

在这里插入图片描述

3

在这里插入图片描述

4

image-20240229230949408

cbv源码的执行流程

​ CBV(Class-Based Views)是一种处理HTTP请求的方式,相比FBV(Function-Based Views)更加灵活和易于维护。CBV源码的执行流程大致如下:

  1. URL匹配和路由分发:当一个HTTP请求到达Django应用时,Django会根据URL配置文件中的路由规则将请求分发到相应的视图函数。
  2. 视图函数调用:对于CBV,路由规则通常会指向一个继承自Django提供的特定类的视图类,而不是一个普通的函数。当请求到达相应的视图类时,Django会实例化该类,并调用其中的dispatch方法。
  3. dispatch方法dispatch方法是CBV执行的入口。在dispatch方法中,Django会根据请求的HTTP方法(GET、POST、PUT等)调用相应的处理方法,例如getpostput等。
  4. 请求处理方法:在视图类中,通常会定义一系列处理请求的方法,如getpost等。这些方法接收请求对象作为参数,并根据请求的具体情况执行相应的逻辑。
  5. Mixin扩展:CBV可以通过Mixin类来扩展功能。Mixin类是一种特殊的类,可以通过多重继承的方式将其添加到视图类中,从而为视图类提供额外的功能,例如身份验证、缓存等。
  6. 模板渲染:在视图类中,可以通过调用render方法来渲染模板并生成HTML响应。render方法接收模板名称和上下文数据作为参数,并返回渲染后的HTML内容。
  7. 响应返回:最后,视图类会生成一个HTTP响应对象,并将其返回给客户端。这个响应对象通常包含HTTP状态码、响应头和响应体等信息。

​ 总的来说,CBV的执行流程可以简单概括为:URL匹配和路由分发 → 视图函数调用 → dispatch方法 → 请求处理方法 → 模板渲染 → 响应返回。

【二】在视图层View编写5个接口

  • 什么是csrf

    • CSRF 就是攻击者利用一个用户已经登录的身份,在用户不知情的情况下对另一个网站或应用发起恶意请求。
  • 防止的措施

    • CSRF Token:在用户登录时生成一个随机的 token,并将其嵌入到表单或请求的参数中,在后续的请求中验证这个 token 的有效性,确保请求来源合法。
    • SameSite Cookie 属性:设置 Cookie 的 SameSite 属性,限制 Cookie 只能在相同站点请求中发送,防止跨站点请求。
    • 验证 Referer:验证请求的 Referer 头部,确保请求来源合法。
    • 双重提交 Cookie:将一个随机值存储在 Cookie 中,并在表单中将这个值作为参数发送,在服务器端验证这个值与 Cookie 中的值是否匹配。
基于View编写5个接口--csrf
	-序列化自己做--》JsonResponse
    	多条--for 字典--》追加到列表中
        单体
        新增
        修改
        删除 

【0】前提条件

​ 继承View编写修改接口,让他使用json格式提交数据,修改成功
​ 写一个装饰器,装饰视图函数FBV,使得request有data属性,无论哪种编码和请求方式,都是字典

【1】准备Book的数据

  • 创建一个名为Book表跟book的数据库

  • 启动MySQL

net start mysql
  • 输入密码的两种方式
---mysql -u root -P 3306 -p
--- mysql -u root -p
********************

image-20240411224416105

  • 在model.py文件中创建数据库
from django.db import models

# Create your models here.
class Book(models.Model):
    name = models.CharField(max_length=88)
    price = models.IntegerField()
    publish = models.CharField(max_length=66)
  • 前提是先在settings.py文件中先定义
DATABASES = {
    'default': {
        # 数据库引擎选择使用MySQL
        'ENGINE': 'django.db.backends.mysql',
        # 指定数据库名字,需提前创建
        'NAME': 'books',
        # 指定数据库用户名
        'USER': 'root',
        # 指定数据库用户密码
        'PASSWORD': '123123',
        # 指定数据库连接IP
        'HOST': '127.0.0.1',
        # 指定数据库端口
        'PORT': 3306,
        # 指定数据库默认编码集(可选)
        'CHARSET': 'utf8mb4',

    }
}
  • 数据迁移
''' python manage.py makemigrations
 python manage.py migrate '''

【2】在views

  • 第一步

from django.http import JsonResponse
import re
import json
from urllib.parse import unquote
# Create your views here.
from django.utils.decorators import method_decorator
from django.views import View
from .models import Book
class BookView(View):
    def get(self, request):
        res_list = Book.objects.all()
        data_list = []
        for res in res_list:
            data_list.append({'name': res.name, 'price': res.price, 'publish': res.publish})
        return JsonResponse({'code': 100, 'msg': '查询成功', 'results': data_list})

    def post(self, request):
        # 前端无论以什么编码格式--》提交到后端你的数据,都会被解析到 request.data 中,是个字典
        # 如果是urlencoded或form-data编码--》不能直接这样写,要写成如下
        data = request.POST
        book = Book.objects.create(name=data.get('name'), price=data.get('price'), publish=data.get('publish'))
        return JsonResponse({'code': 100, 'msg': '新增成功'})
        # 如果是json格式编码,下面没问题
        # Book.objects.create(**request.data)

        print(request.POST)
        print(request.data)
        # 本质原因是?
        ''' APIView帮咱们呢---》看POST中有没有数据,如果有,直接赋值给data,如果没有,他去body中转成字典再给data
         json格式:
            POST没有东西 QueryDict
            data有数据  dict
        urlencoded或form-data
            POST有东西 QueryDict
            data有数据  QueryDict
        '''
        return JsonResponse({'code': 100, 'msg': '新增成功'})




# 127.0.0.1:8000/app01/books/1
@method_decorator(outter,'post')
# @method_decorator(outter,'delete')
class BookDetailView(View):
    def get(self, request, pk):
        res = Book.objects.filter(pk=pk).first()
        # 加个逻辑判断
        return JsonResponse(
            {'code': 100, 'msg': '查询成功', 'result': {'name': res.name, 'price': res.price, 'publish': res.publish}})

    def delete(self, request, pk):
        try:
            # 尝试从数据库中获取指定主键的对象
            book = Book.objects.get(pk=pk)
        except Book.DoesNotExist:
            # 如果对象不存在,则返回相应的 JSON 响应
            return JsonResponse({'code': 200, 'msg': '没有数据!!!'})

        # 如果对象存在,则删除它
        book.delete()

        # 返回删除成功的 JSON 响应
        return JsonResponse({'code': 100, 'msg': '删除成功'})

    def put(self, request, pk):
        # 跟post新增数据一样,编码格式不是json就会报错
        print(request.body)
        data = request.body
        res_data = json.loads(data)
        print(res_data)

        name = res_data.get('name')
        price = res_data.get('price')
        publish = res_data.get('publish')

        Book.objects.filter(pk=pk).update(name=name,
                                          price=price,
                                          publish=publish)
        return JsonResponse({'code': 100, 'msg': '修改成功'})

    def post(self, request):
        # body gen body的使用方法
        # print(request.body)
        # ta = request.body
        # da = json.loads(ta)


        name = request.POST.get('name')
        price = request.POST.get('price')
        publish = request.POST.get('publish')


        # 保存任务到数据库
        res = Book.objects.create(
            name=name,
            price=price,
            publish=publish,

        )

        return JsonResponse({'code': 100, 'msg': '添加成功', 'result': {'name': res.name, 'price': res.price, 'publish': res.publish}})

  • 第二步

​ 添加一个装饰器才能实现无论哪种编码和请求方式,都是字典

def outter(func):
    def inner(*args, **kwargs):
        data = None
        request = args[0]
        content_type = request.META.get('CONTENT_TYPE')
        if 'json' in content_type:
            data = json.loads(request.body)
        elif 'urlencoded' in content_type:
            data = request.body.decode('utf-8')
            # 将查询字符串拆分为键值对列表
            body_list = data.split('&')

            decode = {}
            for body in body_list:
                decode[body.split("=")[0]] = unquote(body.split("=")[1])
                print(decode)

            # 最终得到的解析后的字典
            data = decode
        elif 'form-data' in content_type:
            data = request.body.decode('utf8')
            pattern = r'Content-Disposition: form-data; name="([^"]+)"\s*\r\n\s*\r\n(.*?)(?=\r\n|--.*?--|\Z)'
            res = re.findall(pattern, string=data)
            data = {i[0]: i[1] for i in res}
        request.data = data
        res = func(*args, **kwargs)
        return res

    return inner

​ 这个装饰器的内部函数 inner 接收任意数量的位置参数 args 和关键字参数 kwargs,然后提取第一个位置参数(即 HTTP 请求对象)并赋值给 request 变量。接下来,它获取请求的 Content-Type,根据不同的 Content-Type 类型对请求的 body 数据进行解析,并将解析后的数据存储在 data 变量中。

  • 如果 Content-Type 中包含 ‘json’,则将请求的 body 数据解析为 JSON 格式。
  • 如果 Content-Type 中包含 ‘urlencoded’,则将请求的 body 数据解析为 URL 编码格式,并将其拆分为键值对列表,然后使用列表推导式和解码函数 unquote 将每个键值对进行解码,并构建成字典。
  • 如果 Content-Type 中包含 ‘form-data’,则使用正则表达式从 body 数据中提取键值对,并将其存储为字典格式。

第一句代码 data = {i[0]: unquote(i[-1]) for i in [info.split('=') for info in data.split('&')]} 是用来解析 URL 编码格式的数据。具体解释如下:

  • data.split('&'): 这一部分将请求的 body 数据按照 ‘&’ 符号进行拆分,得到一个包含键值对的列表。
  • [info.split('=') for info in data.split('&')]: 这一部分使用列表推导式,对上一步得到的列表中的每个键值对进行拆分,按照 ‘=’ 符号将键值对分成键和值,并构成一个新的列表。
  • {i[0]: unquote(i[-1]) for i in [info.split('=') for info in data.split('&')]}: 这一部分再次使用列表推导式,对拆分后的键值对列表中的每个元素进行处理。其中,i[0] 表示取每个键值对中的键,而 i[-1] 表示取每个键值对中的值。然后使用 unquote 函数对值进行 URL 解码,最终构建成一个字典,键为解码后的键,值为解码后的值。

第二句代码 pattern = r'Content-Disposition: form-data; name="([^"]+)"\s*\r\n\s*\r\n(.*?)(?=\r\n|--.*?--|\Z)' 是用来解析 form-data 格式的数据。具体解释如下:

  • r'Content-Disposition: form-data; name="([^"]+)"\s*\r\n\s*\r\n(.*?)(?=\r\n|--.*?--|\Z)'
    

    : 这是一个正则表达式,用于匹配 form-data 类型的数据。在 form-data 中,每个键值对由两部分组成:名称(name)和值。这个正则表达式的主要作用是匹配 form-data 中的名称和值。

    • Content-Disposition: form-data; name="([^"]+)": 这一部分匹配了 form-data 中的名称,使用了括号捕获组 ([^"]+) 来匹配名称的值,即键。
    • \s*\r\n\s*\r\n: 这一部分匹配了 form-data 中键值对之间的空行,即键值对之间的分隔符。
    • (.*?): 这一部分匹配了 form-data 中的值,使用了非贪婪匹配 .*? 来匹配任意字符,直到下一个分隔符或者结束符。
    • (?=\r\n|--.*?--|\Z): 这一部分是一个前瞻断言,用于确定值的结束位置。它匹配了一个空行 \r\n 或者 form-data 结束符 --.*?-- 或者字符串的结尾 \Z

【3】在urls

先在主路由先实现一个路由分发

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('Api01/', include('Api01.urls')),
]

子路由

from django.urls import path,include
# BookView、BookDetailView 这个就是我在views.py 定义的类
from Api01.views import BookView,BookDetailView
urlpatterns = [
    path('books/', BookDetailView.as_view()),
    path('books/<int:pk>/', BookDetailView.as_view()),

]

【4】在postman进行检验

具体其他的自己练

image-20240411231213457

image-20240411230941768

image-20240411231017754

【5】注意事项

​ 在下面的实例来说这里的在Task表的取值就是就是用request.body就是只能使用python中反序列化

​ 因为它返回的是一个字典的形式

'''b'{"task_name":"jian","task_desc":"666"}'
{'task_name': 'jian', 'task_desc': '666'}
<class 'dict'>
Task object (3)
jian '''

例如:

import json

# 假设 request.body 就是你提供的字节串
body_bytes = b'{"task_name":"jian","task_desc":"666"}'

# 将字节串解析为 Python 字典对象
body_dict = json.loads(body_bytes)

# 现在可以访问 body_dict 中的数据了
print(body_dict['task_name'])  # 输出 'jian'
print(body_dict['task_desc'])  # 输出 '666'
def put(self, request, id):
    try:
        print(request.body)
        data = request.body
        calssdatda = json.loads(data)
        print(calssdatda)
        print(type(calssdatda))
        # <class 'dict'>



        task = Task.objects.get(id=id)
        print(task)
        task_name = calssdatda.get('task_name')
        print(task_name)
        task_desc = calssdatda.get('task_desc')
        task_time = time.strftime('%Y-%m-%d')

        # 更新任务信息

        task.task_name = task_name
        task.task_desc = task_desc
        task.task_time = task_time
        task.save()

        return JsonResponse({'message': 'Task 更新成功'})
    except Task.DoesNotExist:
        return JsonResponse({'error': '未找到数据'}, status=404)
  • 所以我们在使用postman只能用raw中json方法

  • image-20240411233939594

image-20240411232917536

示例二

  • 准备工作

# models.py
from django.db import models


class Book(models.Model):
    name = models.CharField(max_length=88)
    price = models.IntegerField()
    publish = models.CharField(max_length=66)
  • View跟APIView这个两个方法区别并不大

# views.py
class BookView(APIView):
    def get(self, request):
        res_list = Book.objects.all()
        data_list = []
        for res in res_list:
            data_list.append({'name': res.name, 'price': res.price, 'publish': res.publish})
        return JsonResponse({'code': 100, 'msg': '查询成功', 'results': data_list})

    def post(self, request):
        # 前端无论以什么编码格式--》提交到后端你的数据,都会被解析到 request.data 中,是个字典
        # 如果是urlencoded或form-data编码--》不能直接这样写,要写成如下
        data = request.POST
        book = Book.objects.create(name=data.get('name'), price=data.get('price'), publish=data.get('publish'))
        return JsonResponse({'code': 100, 'msg': '新增成功'})
        # 如果是json格式编码,下面没问题
        # Book.objects.create(**request.data)

        print(request.POST)
        print(request.data)
        # 本质原因是?
        ''' APIView帮咱们呢---》看POST中有没有数据,如果有,直接赋值给data,如果没有,他去body中转成字典再给data
         json格式:
            POST没有东西 QueryDict
            data有数据  dict
        urlencoded或form-data
            POST有东西 QueryDict
            data有数据  QueryDict
        '''
        return JsonResponse({'code': 100, 'msg': '新增成功'})
  • 这个是我写的装饰器
  • 这个装饰器根据请求的 Content-Type 头部信息来判断请求发送的数据类型,然后将数据解析为相应的格式,并存储在请求对象的 data 属性中。解析的数据包括 JSON 格式、urlencoded 格式和 form-data 格式。
  • 白话文就是可以让我随便使用JSON格式、urlencoded格式和form-data格式。
def outter(func):
    def inner(*args, **kwargs):
        data = None
        request = args[0]
        content_type = request.META.get('CONTENT_TYPE')
        if 'json' in content_type:
            data = json.loads(request.body)
        elif 'urlencoded' in content_type:
            data = request.body.decode('utf-8')
            # 将查询字符串拆分为键值对列表
            body_list = data.split('&')

            decode = {}
            for body in body_list:
                decode[body.split("=")[0]] = unquote(body.split("=")[1])
                print(decode)

            # 最终得到的解析后的字典
            data = decode
        elif 'form-data' in content_type:
            data = request.body.decode('utf8')
            pattern = r'Content-Disposition: form-data; name="([^"]+)"\s*\r\n\s*\r\n(.*?)(?=\r\n|--.*?--|\Z)'
            res = re.findall(pattern, string=data)
            data = {i[0]: i[1] for i in res}
        request.data = data
        res = func(*args, **kwargs)
        return res

    return inner
  • urls.py

from django.urls import path,include
# BookView、BookDetailView 这个就是我在views.py 定义的类
from Api01.views import BookView,BookDetailView
urlpatterns = [
    path('books/', BookDetailView.as_view()),
    path('books/<int:pk>/', BookDetailView.as_view()),

]

image-20240412204356592

  • 这个是View方法
@method_decorator(outter,'post')
# @method_decorator(outter,'delete')
class BookDetailView(View):
    def get(self, request, pk):
        res = Book.objects.filter(pk=pk).first()
        # 加个逻辑判断
        return JsonResponse(
            {'code': 100, 'msg': '查询成功', 'result': {'name': res.name, 'price': res.price, 'publish': res.publish}})

    def delete(self, request, pk):
        try:
            # 尝试从数据库中获取指定主键的对象
            book = Book.objects.get(pk=pk)
        except Book.DoesNotExist:
            # 如果对象不存在,则返回相应的 JSON 响应
            return JsonResponse({'code': 200, 'msg': '没有数据!!!'})

        # 如果对象存在,则删除它
        book.delete()

        # 返回删除成功的 JSON 响应
        return JsonResponse({'code': 100, 'msg': '删除成功'})

    def put(self, request, pk):
        # 跟post新增数据一样,编码格式不是json就会报错
        Book.objects.filter(pk=pk).update(**request.data)
        return JsonResponse({'code': 100, 'msg': '修改成功'})

    def post(self, request):
        # body gen body的使用方法
        # print(request.body)
        # ta = request.body
        # da = json.loads(ta)


        name = request.POST.get('name')
        price = request.POST.get('price')
        publish = request.POST.get('publish')


        # 保存任务到数据库
        res = Book.objects.create(
            name=name,
            price=price,
            publish=publish,

        )

        return JsonResponse({'code': 100, 'msg': '添加成功', 'result': {'name': res.name, 'price': res.price, 'publish': res.publish}})

image-20240412211832202

【三】APIView编写5个接口

  • 去除了csrf
    • 由于 RESTful API 通常是无状态的,不需要使用 CSRF 防护机制,因此 DRF 的 APIView 默认情况下去除了 CSRF 防护。
  • 包装新的request
    • 包装新的 request:APIView 提供了更灵活的请求(request)对象的访问方式,允许开发者更方便地访问请求中的数据以及请求的元数据。
  • 三大认证
    • APIView 支持多种身份验证方式,包括基于 Token 的认证、基于 Session 的认证、基于 OAuth 的认证等,使得开发者可以根据需求选择适合的认证方式。
  • 全局异常捕获
    • APIView 具有全局异常捕获的功能,可以捕获视图中发生的异常,并返回自定义的错误响应,提高了代码的可维护性和可靠性。

【0】注意事项

​ 视图(View)和API视图(APIView)都可以包含处理请求的逻辑,并且它们都可以执行相似的操作,比如从请求中获取数据、执行业务逻辑、与数据库交互等。

然而,它们之间仍然存在一些区别:

  1. 设计目的:视图通常用于渲染HTML页面,而API视图则用于处理API请求并返回数据,通常以JSON格式。
  2. 功能和便利性:API视图(特别是DRF中的APIView)通常提供了更多的功能和便利性,比如内置的请求处理方法(如getpost等)、序列化、验证、权限控制、分页等。这些功能可以帮助简化API开发并提高开发效率。
  3. 返回响应的方式:API视图通常使用DRF提供的Response对象来返回响应,而视图可能使用Django的render函数或者HttpResponse对象。

​ 虽然视图和API视图在处理请求的逻辑上可能非常相似,但是选择合适的工具(视图或API视图)取决于你的具体需求和项目的特点。如果你正在构建一个RESTful API,那么使用API视图可能会更加合适和便捷。

【1】主路由urls.py

from django.contrib import admin
from django.urls import path,include # 路由分发

urlpatterns = [
    path('admin/', admin.site.urls),
    path('task_api/', include('task_api.urls')),
]

【2】子路由urls.py

from django.urls import path,include,re_path
from task_api.views import TaskAPIView ,TaskDetailView # TaskView

urlpatterns = [
    # re_path(r'(?P<id>\d+)?/?$', TaskAPIView.as_view()),
    re_path(r'(?P<pk>\d+)?/?$', TaskDetailView.as_view()),
]

【3】views.py

from django.http import JsonResponse
from .models import Task 
import time
import uuid

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class TaskAPIView(APIView):
    def post(self, request):
        # 获取POST请求中的数据
        task_name = request.POST.get('task_name')
        task_desc = request.POST.get('task_desc')
        # 生成任务时间
        task_time = time.strftime('%Y-%m-%d')
        # 生成任务ID
        task_id = uuid.uuid4()

        # 保存任务到数据库
        Task.objects.create(
            task_name=task_name,
            task_desc=task_desc,
            task_time=task_time,
            task_id=task_id
        )

        # 返回JSON响应    是一个HTTP状态码返回成功则是"201 Created"
        return Response({'message': 'Task 添加成功!'}, status=status.HTTP_201_CREATED)

    def get(self,request):
        res_list = Task.objects.all()
        data_list = []
        for res in res_list:
            data_list.append({'task_name': res.task_name,'task_desc':res.task_desc,'task_time':res.task_time,'task_id':res.task_id})
        return JsonResponse({'code': 100, 'msg': '查询成功', 'results': data_list})

class TaskDetailView(APIView):
    def get(self,request,pk):
        if pk:
            try:
                task = Task.objects.get(pk=pk)
                print(task)
                data = {

                    'task_name': task.task_name,
                    'task_desc': task.task_desc,
                    'task_time': task.task_time,
                    'task_id': task.task_id
                }
                print(data)
                return JsonResponse(data)
            except Task.DoesNotExist:
                return JsonResponse({'error': 'Task 未能发现数据'}, status=404)


    def delete(self, request, pk):
        if pk:
            try:
                Task.objects.filter(pk=pk).delete()
                return JsonResponse({'code': 100, 'msg': '删除成功'})
            except Task.DoesNotExist:
                return JsonResponse({'error': 'Task 未能发现数据'}, status=404)

    def put(self, request, pk):
        if pk:
            try:
                Task.objects.filter(pk=pk).update(**request.data)
                return JsonResponse({'code': 100, 'msg': '修改成功!!!'})
            except Task.DoesNotExist:
                return JsonResponse({'error': 'Task 未能发现数据'}, status=404)

image-20240412190754671

image-20240412190819207

问:

​ 这个**request.data按你所说就是一个将Task表中的数据渲染到前端然后在解包打印到后端的过程对不对

答:

​ 不完全正确。request.data并不是将数据库中的数据直接渲染到前端,而是在Django REST Framework中用于获取HTTP请求中发送的数据的方式之一。具体来说,request.data是一个包含了HTTP请求主体中发送的数据的字典,它可能是通过POST、PUT或PATCH等HTTP方法发送的。

​ 在你的情况下,假设你使用的是PUT方法来更新任务的数据,那么request.data将包含前端发送的要更新的任务数据。而**request.data这个语法是将这个字典中的键值对解包为关键字参数,然后将这些参数传递给update()函数,以更新数据库中对应任务的数据。

​ 所以,request.data不是将数据库中的数据直接渲染到前端,而是用于获取HTTP请求中发送的数据,并在后端进行处理和操作。

request.data-->请求体的数据--》方法包装成了数据属性
  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值