drf知识-08

Django之了解DRF框架

# 介绍:DRF全称 django rest framework

# 背景:

        在序列化与反序列化时,虽然操作的数据不尽相同,但是执行的过程却是相似的,也就是说这部分代码是可以复用简化编写
        增:校验请求数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
        删:判断要删除的数据是否存在 -> 执行数据库删除
        改:判断要修改的数据是否存在 -> 校验请求的数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
        查:查询数据库 -> 将数据序列化并返回
# 作用:Django REST framework可以帮助我们简化上述两部分的代码编写,大大提高REST API的开发速度

# DRF特点:

        1.提供了定义序列化器Serializer的方法,可以快速根据 Django ORM 或者其它库自动序列化/反序列化;
        2.提供了丰富的类视图、Mixin扩展类,简化视图的编写;
        3.丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要;
        4.多种身份认证和权限认证方式的支持;
        5.内置了限流系统;
        6.直观的 API web 界面;
        7.可扩展性,插件丰富

# 环境安装与配置:

1、安装DRF

pip install djangorestframework

2、在settings.py的INSTALLED_APPS中添加’rest_framework’

INSTALLED_APPS = [...'rest_framework',
]

# DRF牛刀小试:

1、创建序列化器,在books应用中新建serializers.py用于保存该应用的序列化器,创建一个类用于序列化与反序列化:

from rest_framework import serializers
from books.models import Bookclass BookInfoSerializer(serializers.ModelSerializer):"""图书数据序列化器"""class Meta:model = Bookfields = '__all__'

        model 指明该序列化器处理的数据字段从模型类Book参考生成
        fields 指明该序列化器包含模型类中的哪些字段,'all’指明包含所有字段

2、编写视图,在books应用的views.py中创建视图BookViewSet,这是一个视图集合:

from rest_framework.viewsets import ModelViewSet
from .serializers import BookSerializer
from .models import Bookclass BookViewSet(ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializer

        queryset 指明该视图集在查询数据时使用的查询集
        serializer_class 指明该视图在进行序列化或反序列化时使用的序列化器

3、定义路由,在books应用的urls.py中定义路由信息

from . import views
from rest_framework.routers import DefaultRouterrouter = DefaultRouter()  # 可以处理视图的路由器
router.register(r'books', views.BookViewSet, 'books')  # 向路由器中注册视图集
urlpatterns = [
]
urlpatterns += router.urls  # 将路由器中的所以路由信息追到到django的路由列表中

三大认证组件回顾

# 认证类的编写
用户登录后,会有登录标识,早期直接写入到浏览器中了

session['name']='lqz'
obj.set_cookie()

写认证类的目的:校验它携带的登录标识,是否合法,是否在库中存着
只需要按照固定规则去写即可:
  1、写一个类,继承 BaseAuthentication
  2、重写 authenticate 方法
  3、在方法中完成校验--》用户标识

             用户标识带在请求头 / 请求地址 / 请求体
            校验携带的标识正不正确---> 去数据库查
            查到返回俩值:第一个值会给后续的request.user,第二个值给request.auth
            校验失败:抛异常

class LoginAuth(BaseAuthentication):   # 不一定继承BaseAuthenticationdef authenticate(self, request):   # 目的是重写authenticate,有authenticate就是认证类token = request.query_params.get('token') or request.META.get('HTTP_TOKEN')user_token = UserToken.objects.filter(token=token).first()if user_token:user = user_token.user      # 重写是因为源码里在一个个调用这个方法,在方法中完成校验return user, user_token     # 返回两个值,第一个值会给request.user,第二个给了request.authelse:                           # 标识一般带到请求头、请求地址和请求体中,由后端决定raise AuthenticationFailed("您没有登录")

  4、放在视图类上,局部禁用:
            authentication_classes=[ ]
 5、放在配置文件中--drf配置文件中找 :         

 REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['app01.auth.LoginAuth'],}

#  权限类
  用户登录了,有没有权限访问接口
  权限放在了认证之后,request.user :当前登录用户,根据是谁来做权限
  编写规则:
 1、写一个类类,继承 BasePermission
 2、 重写 has_permission 方法
 3、在方法中完成权限校验--》当前登录用户
            能有用户,就能取出用户的权限
            如果有,返回True,没有返回False
            前端看到中文提示:self.message

class CommonPermission(BasePermission):def has_permission(self, request, view):try:user_type = request.user.user_typeif user_type == 2:return Trueelse:# user.get_字段名_display()  返回这个字段的choice对应的文字self.message = '您是:%s,您没有权限操作这个' % request.user.get_user_type_display()return Falseexcept Exception as e:# 未登录用户也没有权限if 'login' in request.path:return Trueelse:self.message = '您没有登录,您没有权限操作这个'return False

  4、放在视图类上(可以配多个),局部禁用:
            permission_classes=[ ]
 5、放在配置文件中--drf配置文件中找:

 REST_FRAMEWORK = {'DEFAULT_permission_CLASSES': [''],}

# 频率类使用
限制用户访问频次:用户登录或不登录都可能会限制
限制条件:ip,用户id
编写步骤:
    1、写一个类类,继承 SimpleRateThrottle
    2、重写 get_cache_key 方法
           返回什么就以什么做限制:ip或id号
            类上写个属性:rate = '5/d'    # s m h d 

class CommonThrottle(SimpleRateThrottle):rate = '3/m'def get_cache_key(self, request, view):ip = request.META.get('REMOTE_ADDR')return ip

  3、放在视图类上(可以配多个),局部禁用:
            throttle_classes=[ ]
  4、 放在配置文件中--drf配置文件中找:            

REST_FRAMEWORK = {'DEFAULT_throttle_CLASSES': [''],}

排序之继承GenericAPIView

# 1 只有查询所有需要排序
# 2 如何使用
     1 必须是继承 GenericAPIView 及其子类
    2 在类中配置类属性
        filter_backends = [OrderingFilter]
    3 类中写属性
        ordering_fields = ['price','id']  # 必须表的字段        
    4 以后再前端,就可以访问
        http://127.0.0.1:8000/api/v1/books/?ordering=price 按price升序排
        http://127.0.0.1:8000/api/v1/books/?ordering=-price 按price降序排
        http://127.0.0.1:8000/api/v1/books/?ordering=-price,id

from .models import Book
from rest_framework.viewsets import ViewSetMixin
from rest_framework.generics import ListAPIView
from .serializer import BookSerializer# 排序之继承 GenericAPIView
from rest_framework.filters import OrderingFilter
class BookView(ViewSetMixin,ListAPIView):     # 改路径和查询所有queryset = Book.objects.all()serializer_class = BookSerializer   # 序列类映射filter_backends = [OrderingFilter]  # 排序ordering_fields = ['price','id']# http://127.0.0.1:8000/api/v1/books/?ordering=-price,id

排序之继承APIview

# 如果继承APIView,过滤规则自己写

# 单条排序:

# 排序之继承 APIView
from rest_framework.views import APIView
from rest_framework.response import Response
class BookView(ViewSetMixin, APIView):def list(self, request):# 从地址兰中取出用户过滤条件# http://127.0.0.1:7000/api/v1/books/?ordering=-pricequery_params = request.query_params  #< QueryDict: {'ordering': ['-price']}>obj_list = Book.objects.all().order_by(query_params.get('ordering'))ser = BookSerializer(instance=obj_list, many=True)return Response(ser.data)

# 多条排序:

# 排序之继承 APIView
from rest_framework.views import APIView
from rest_framework.response import Response
class BookView(ViewSetMixin, APIView):def list(self, request):# 从地址兰中取出用户过滤条件# http://127.0.0.1:7000/api/v1/books/?ordering=-price,idquery_params = request.query_params  #<QueryDict: {'ordering': ['-price,id']}>print(query_params)if ',' in query_params.get('ordering'):query = query_params.get('ordering').split(',')obj_list = Book.objects.all().order_by(*query)ser = BookSerializer(instance=obj_list, many=True)return Response(ser.data)

过滤之使用drf内置过滤类

#  restful规范中有一条是请求地址中带过滤条件,查询所有数据,只查询出我们想要的

# 如何使用
     1 必须是继承 GenericAPIView 及其子类
     2 在类中配置类属性
        filter_backends = [SearchFilter]
     3 类中写属性
       search_fields = ['price','id']  # 必须表的字段        
    4 以后再前端,就可以访问
        http://127.0.0.1:7000/api/v1/books/?search=风

        http://127.0.0.1:7000/api/v1/books/?search=摆

# 过滤之使用drf内置过滤类
from rest_framework.filters import SearchFilter
class BookView(ViewSetMixin,ListAPIView):     # 改路径和查询所有queryset = Book.objects.all()serializer_class = BookSerializer   # 序列类映射filter_backends = [SearchFilter]  # 排序search_fields = ['name']# http://127.0.0.1:7000/api/v1/books/?search=风

过滤之使用djagno-filter过滤

# 下载  pip3 install django-filter

# 导入  from django_filters.rest_framework import DjangoFilterBackend
# 3 使用

# 过滤之使用djagno-filter过滤
from django_filters.rest_framework import DjangoFilterBackend
class BookView(ViewSetMixin,ListAPIView):     # 改路径和查询所有queryset = Book.objects.all()serializer_class = BookSerializer   # 序列类映射filter_backends = [DjangoFilterBackend]  # 排序filterset_fields = ['name','price']# http://127.0.0.1:7000/api/v1/books/?name=摆渡人&price=34# 查询书名为摆渡人且价格为34的

过滤之自定制过滤类

# 写个类,继承BaseFilterBackend重写filter_queryset,在内部完成过滤

# filter
from rest_framework.filters import BaseFilterBackend
class CommonFilter(BaseFilterBackend):def filter_queryset(self, request, queryset, view):# queryset 是之前所有数据 Book.object.all()# request 当次请求requestname = request.query_params.get('name')price = request.query_params.get('price')if name:queryset = queryset.filter(name__contains=name)if price:queryset = queryset.filter(price=price)return queryset
# views.py
# 过滤之自定制过滤类,重写了类里方法,再引用
from .filter import CommonFilter
class BookView(ViewSetMixin,ListAPIView):     # 改路径和查询所有queryset = Book.objects.all()serializer_class = BookSerializer   # 序列类映射filter_backends = [CommonFilter]  # 排序# http://127.0.0.1:7000/api/v1/books/?name=追&price=31.2# 书名用了模糊查法,价格是精准查法

自定义过滤+排序

# 自定义过滤+排序
from .filter import CommonFilter
from rest_framework.filters import OrderingFilter
class BookView(ViewSetMixin,ListAPIView):     # 改路径和查询所有queryset = Book.objects.all()serializer_class = BookSerializer   # 序列类映射filter_backends = [CommonFilter,OrderingFilter]  # 过滤,排序ordering_fields = ['price']# http://127.0.0.1:7000/api/v1/books/?name=渡&ordering=-price# 查询书名含渡的且按照价格降序

分页之基础分页

# 查询所有接口,分页

# 使用drf内置了三种分页方式:

        PageNumberPagination, LimitOffsetPagination, CursorPagination

1、写个类,继承基础分页类,重写类属性       

# pagination.py  基本分页PageNumberPagination
from rest_framework.pagination import PageNumberPagination
class CommonPageNumberPagination(PageNumberPagination):page_size = 1      # 默认显示,每页大小,一页显示多少条page_query_param = 'page'    # 分页查询条件  ?page=1page_size_query_param = 'size'  #每页最多显示多少条的查询条件  &size=2max_page_size = 3   # 每页最多显示多少条# http://127.0.0.1:7000/api/v1/books/?search=34&size=2# 过滤查询价格为34且一页显示2条数据的(不写size默认显示1条)

2、在继承自 GenericAPIView及其子类, 在视图类配置分页类即可

# 分页之基础分页
# 在内置过滤器的条件下分页
from rest_framework.filters import SearchFilter
from .pagination import CommonPageNumberPagination
class BookView(ViewSetMixin,ListAPIView):     # 改路径和查询所有queryset = Book.objects.all()serializer_class = BookSerializer   # 序列类映射filter_backends = [SearchFilter]  # 过滤,排序search_fields = ['price']pagination_class = CommonPageNumberPagination

分页之偏移分页

 # 查询所有接口,分页

# 使用drf内置了三种分页方式:

        PageNumberPagination, LimitOffsetPagination, CursorPagination

1、写个类,继承基础分页类,重写类属性       

# pagination.py  基本分页LimitOffsetPagination
from rest_framework.pagination import LimitOffsetPagination
class CommonLimitOffsetPagination(LimitOffsetPagination):default_limit = 1   # 默认显示,每页显示的条数limit_query_param = 'limit'  # 分页查询条件  ?limit=1offset_query_param = 'offset'   # # 偏移量 从第2条开始,拿2条 offset=2&limit=2max_limit = 3   # # 每页最多显示多少条# http://127.0.0.1:7000/api/v1/books/?limit=1&page=3  显示第三页的一条数据# http://127.0.0.1:7000/api/v1/books/?offset=1&limit=2  从第一条数据开始显示2条数据

2、在继承自 GenericAPIView及其子类, 在视图类配置分页类即可

# 分页之基础分页
# 在内置过滤器的条件下分页
from rest_framework.filters import SearchFilter
from .pagination import CommonPageNumberPagination
from .pagination import CommonLimitOffsetPagination
class BookView(ViewSetMixin,ListAPIView):     # 改路径和查询所有queryset = Book.objects.all()serializer_class = BookSerializer   # 序列类映射filter_backends = [SearchFilter]  # 过滤,排序search_fields = ['price']pagination_class = CommonPageNumberPaginationpagination_class = CommonLimitOffsetPagination

分页之游标分页

# 特点:只能从第一页开始,只能上一页和下一页,不能自定义哪页,但是效率高很多

1、写个类,继承基础分页类,重写类属性       

# pagination.py 游标分页  CursorPagination
from rest_framework.pagination import CursorPagination
class CommonCursorPagination(CursorPagination):cursor_query_param = 'cursor'   # 分页查询条件  ?cursor=1page_size = 2    # 每页显示的条数ordering = 'id'  # 排序规则,必须是表中字段# http://127.0.0.1:7000/api/v1/books/# 内部已经写死,从第一页查起,显示2条,只能上下翻页

2、在继承自 GenericAPIView及其子类, 在视图类配置分页类即可

# views.py
# 分页之基础分页
# 在内置过滤器的条件下分页
from rest_framework.filters import SearchFilter
from .pagination import CommonPageNumberPagination
from .pagination import CommonLimitOffsetPagination
from .pagination import CommonCursorPaginationclass BookView(ViewSetMixin,ListAPIView):     # 改路径和查询所有queryset = Book.objects.all()serializer_class = BookSerializer   # 序列类映射filter_backends = [SearchFilter]  # 过滤,排序search_fields = ['price']pagination_class = CommonPageNumberPaginationpagination_class = CommonLimitOffsetPaginationpagination_class = CommonCursorPagination

全局异常处理

# 三大认证和视图类的方法中出现了异常,都会被try捕获,做全局异常处理

# 捕获到统一处理,无论我是否出异常,返回的格式都是固定的

        {code:100,msg:成功}
# 新建py文件,写一个函数,在函数中处理异常

# exceptions.py
# drf的异常处理是exception_handler处理,没处理非drf的异常
# 自己写个函数,处理drf异常和自己的异常
from rest_framework.views import exception_handler
from rest_framework.response import Responsedef common_exception_handler(exc, context):res = exception_handler(exc, context)  # 处理drf异常处理if res:# data = {'detail': exc.detail},错误信息# return Response(data)# {code: 100, msg: 成功}detail = res.data.get('detil') or "drf异常,请联系系统管理员"return Response({'code': 101, 'msg': detail})else:return Response({'code': 102, 'msg': '系统异常,请联系系统管理员:%s'%str(exc)})

# 把函数配置在配置文件中,setting.py

REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'app01.exceptions.common_exception_handler',}

#  只要三大认证或视图类的方法出了异常,就会走这个函数

# 全局异常处理
# 无论我是否出异常,返回的格式都是固定的
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import AuthenticationFailed,ValidationError,APIExceptionclass UserView(ViewSetMixin, APIView):def create(self, request):  # post--->create# l = [1, 2, 3]# print(l[9])# raise Exception("你出错了")# drf  默认能处理自己的异常:继承自APIException的异常raise APIException('认证失败')return Response({'code': 100, 'msg': '成功'})

今日思维导图:

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

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

相关文章

【《设计模式之美》】如何取舍继承与组合

文章目录 什么情况下不推荐使用继承&#xff1f;组合相比继承有哪些优势&#xff1f;使用组合、继承的时机 本文主要想了解&#xff1a; 为什么组合优于继承&#xff0c;多用组合少用继承。如何使用组合来替代继承哪些情况适用继承、组合。有哪些设计模式使用到了继承、组合。 …

打地鼠游戏来了

主要利用js鼠标点击事件和window.setInterval&#xff08;&#xff09;回调函数来进行实现的. 源码获取方式&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1eW9qvX3zFH9qlH82-I4yOA 提取码&#xff1a;1233

信息安全概论快速复习(期末急救)

文章目录 1、DES中的S-盒输入输出问题 &#xff08;不需要记住S-盒&#xff09;2、Kerberos认证系统3、简答题&#xff08;三题每题8分&#xff09;&#xff1a;课后习题第一章、第三章、第四章第一章&#xff1a;重点关注安全模型内容&#xff0c;有几种&#xff0c;有几个分级…

活动回顾 (下) | 机器学习系统趋势研判,大咖金句汇总

作者&#xff1a;三羊、李宝珠、李玮栋、Yudi、xixi 编辑&#xff1a;李宝珠 在大模型时代的浪潮中&#xff0c;机器学习系统正经历着前所未有的变革。模型规模的急剧膨胀&#xff0c;让我们见证了 AI 能力的巨大提升&#xff0c;然而这种提升不仅为各个领域带来了新的机遇&…

音视频的编码格式与封装格式

音视频的编码格式与封装格式是两个不同的概念&#xff0c;视频封装格式常见的有&#xff1a;mp4&#xff0c;rmvb&#xff0c;avi&#xff0c;mkv&#xff0c;mov&#xff0c;mpg&#xff0c;vob&#xff0c;3gp&#xff0c;asf&#xff0c;rmvb&#xff0c;wmv&#xff0c;div…

关于设计模式、Java基础面试题

前言 之前为了准备面试&#xff0c;收集整理了一些面试题。 本篇文章更新时间2023年12月27日。 最新的内容可以看我的原文&#xff1a;https://www.yuque.com/wfzx/ninzck/cbf0cxkrr6s1kniv 设计模式 单例共有几种写法&#xff1f; 细分起来就有9种&#xff1a;懒汉&#x…

lv13 内核模块动态添加新功能 6

1 动态加载法 即新功能源码与内核其它源码不一起编译&#xff0c;而是独立编译成内核的插件(被称为内核模块&#xff09;文件.ko 1.1 新功能源码与Linux内核源码在同一目录结构下时 给新功能代码配置Kconfig&#xff08;模块代码与上一级相同&#xff09; 给新功能代码改写…

八种常见顺序存储的算法

目录 1、线性枚举 1&#xff09;问题描述 2&#xff09;动图演示 3&#xff09;示例说明 4&#xff09;算法描述 5&#xff09;源码详解 2、前缀和差分 1&#xff09;问题描述 2&#xff09;动图演示 3&#xff09;样例分析 4&#xff09;算法描述 5&#xff09;源码…

Flink Kafka[输入/输出] Connector

本章重点介绍生产环境中最常用到的Flink kafka connector。使用Flink的同学&#xff0c;一定会很熟悉kafka&#xff0c;它是一个分布式的、分区的、多副本的、 支持高吞吐的、发布订阅消息系统。生产环境环境中也经常会跟kafka进行一些数据的交换&#xff0c;比如利用kafka con…

类。。。。

定义一个person类&#xff0c;包含私有成员&#xff0c;int *age,string &name,一个stu类&#xff0c;包含私有成员double *sore,person p1,写出person类和stu类的特殊成员函数&#xff0c;并写一个stu的函数&#xff0c;显示所有信息。 #include <iostream>using n…

Android下载gradle失败解决方法

1、在gradle-wrapper.properties文件中查看自己需要下载gradle什么版本的包和zip路径&#xff08;wrapper/dists&#xff09;。 2、在setting中查看Gradle的保存路径&#xff0c;如下图&#xff1a;C:/Users/Administrator/.gradle&#xff0c;加上第一步的zip路径得到下载grad…

15 Sequence-Driver-Sequencer communication in UVM

我们分别讨论了sequece_item、sequence、sequencer和driver。在本节中&#xff0c;我们将讨论他们如何相互talk&#xff0c;sequencer如何给driver提供从sequence里的sequence item。在开始阅读本节之前&#xff0c;请确保您了解sequencer和driver中使用的所有方法。&#xff0…

Ubuntu fcitx Install

ubuntu经常出现键盘失灵的问题 查询资料得知应该是Ibus框架的问题 于是需要安装fcitx框架和搜狗拼音 sudo apt update sudo apt install fcitx 设置fcitx开机自启动&#xff08;建议&#xff09; sudo cp /usr/share/applications/fcitx.desktop /etc/xdg/autostart/ 然后…

普中STM32-PZ6806L开发板(HAL库函数实现-TIM2实现us延时)

简介 使用TIM2实现1us延时其他知识 公式 时间&#xff08;s&#xff09;1/时钟频率&#xff08;Hz&#xff09;由导出 1us 1/1M(Hz)预分配设置 系统时钟是72MHz, 要1us的延时, 预分配得设置为72-1计数器重载设置 设置为最大值65535&#xff0c;这样延时的时间可以设置的最…

【Vue3】创建项目的方式

1. 基于 vue-cli 创建 ## 查看vue/cli版本&#xff0c;确保vue/cli版本在4.5.0以上 vue --version## 安装或者升级你的vue/cli npm install -g vue/cli## 执行创建命令 vue create vue_test本质上使用webpack&#xff0c;默认安装以下依赖&#xff1a; 2. 基于 vite 创建 官…

Buck电源设计常见的一些问题(五)MOS管振荡抑制方法(三)

MOS管振荡抑制方法(三)Rboot的选取 1.Rboot的选取2.总结1.Rboot的选取 同步 Buck 变换器一般采用自举电路供电,如图所示。开关节点上升沿的振荡与上管开通关系密切,上管开通时的驱动电流路径如图所示。因此,可以通过增大 Rboot来减缓上管开通的速度,从而抑制开关节点的振…

文献速递:人工智能医学影像分割---高效的MR引导CT网络训练,用于CT图像中前列腺分割

01 文献速递介绍 如今&#xff0c;根据国家癌症研究所的报告&#xff0c;美国约有9.9%的男性患有前列腺癌。1 此外&#xff0c;根据美国癌症协会的数据&#xff0c;预计2019年将有174,650个新病例被诊断出前列腺癌&#xff0c;与此同时大约有31,620名男性将死于前列腺癌。因此…

vue前端预览pdf并加水印、ofd文件,控制打印、下载、另存,vue-pdf的使用方法以及在开发中所踩过的坑合集

根据公司的实际项目需求&#xff0c;要求实现对pdf和ofd文件的预览&#xff0c;并且需要限制用户是否可以下载、打印、另存pdf、ofd文件&#xff0c;如果该用户可以打印、下载需要控制每个用户的下载次数以及可打印的次数。正常的预览pdf很简单&#xff0c;直接调用浏览器的预览…

计算机操作系统(OS)——P1操作系统概述

1、操作系统的概念(定义) 1.1、什么是操作系统 __操作系统&#xff08;Operating System&#xff0c;OS&#xff09;&#xff1a;__是指控制和管理整个计算机系统的__硬件和软件__资源&#xff0c;并合理的组织调度计算机的工作和资源的分配&#xff1b;以__提供给用户和其它…

pytest实现多进程与多线程运行超好用的插件

前言 如果想分布式执行用例&#xff0c;用例设计必须遵循以下原则&#xff1a; 1、用例之间都是独立的&#xff0c; 2、用例a不要去依赖用例b 3、用例执行没先后顺序&#xff0c; 4、随机都能执行每个用例都能独立运行成功每个用例都能重复运行&#xff0c;不影响其它用例 这…