Datawhale Django后端开发入门 TASK03 QuerySet和Instance、APIVIew

一、QuerySet

QuerySet 是 Django 中的一个查询集合,它是由 Model.objects 方法返回的,并且可以用于生成数据库中所有满足一定条件的对象的列表。

QuerySet 在 Django 中表示从数据库中获取的对象集合,它是一个可迭代的、类似列表的对象集合。主要特点包括:- 从 Model.objects 获得,表示数据库中所有该 Model 的对象集合。

- 可以添加过滤条件来限制查询结果,如 .filter()、`.exclude()`、`.order_by()` 等。

- 惰性执行,创建 QuerySet 不会立即执行查询,只有在需要求值时才查询数据库。- 可遍历,可以用在 for 循环中进行迭代。- 可切片,使用索引切片来获取一个子集。

- 支持链式调用过滤方法,每个过滤调用返回一个新的 QuerySet。

- 可以获取单个元素,如 .get() 返回单个匹配的对象。

- 支持转换为其他对象列表,如 .values()

- 可以转为字符串执行原始 SQL 查询。所以 QuerySet 是从数据库中获取模型对象数据的一个强大而灵活的接口。正确使用可以最大限度减少数据库查询,提高效率。每个 QuerySet 包含多个 Model 实例(Instance),表示满足查询条件的所有对象实例。

1.filter()方法接收的参数有:- 字段名,比如:.filter(name='John')
- 查询表达式,比如: .filter(age__gt=18)
- Q对象,用于复杂查询,比如:

from django.db.models import Q

queryset.filter(Q(age__gt=18) & Q(name='John'))

关键字参数,比如:.filter(name='John', age__gt=18)filter()会基于给定的参数生成一个新的过滤后的QuerySet。例如:

Article.objects.filter(published=True) # 已发布文章

Article.objects.filter(title__contains='Django') # 标题包含Django的文章

Article.objects.filter(Q(title__contains='Django') | Q(title__contains='Python'))
# 标题包含Django或Python的文章

重要的是,filter()并不会立即执行查询,只是返回一个新的QuerySet,真正的数据库查询会在需要求值的时候发生。我们可以多次调用filter()来链式过滤,每个filter()调用会基于前一个QuerySet然后返回一个新的QuerySet。

2.get()

get()方法与filter()有些类似,主要区别在于:

(1. get()用来获取单个对象,而filter()获取一个对象集合(queryset)。

(2. get()只能返回一个满足条件的对象实例,如果不存在会引发模型类的DoesNotExist异常。

(3. get()无法链接调用,只能获取单个对象。例如:

# 获取id=1的文章
article = Article.objects.get(id=1) 

# 查询标题包含'Python'的文章,如果不存在会报错
article = Article.objects.get(title__contains='Python')

# filter()返回满足条件的所有文章
articles = Article.objects.filter(title__contains='Python')

所以get()主要用于根据过滤条件获取单个对象,这对于获取某个具体模型实例很有用,但需要注意如果不存在会引发异常。而filter()用于获取多个满足条件的对象,这对获取一个QuerySet集合并对其进一步处理很有用。需要根据具体场景选择使用get()还是filter()。

3.all()

Django中的`Model.objects.all()`方法返回该模型的全部对象集合。它相当于没有任何过滤条件的`filter()`查询:

Article.objects.all()
# 等同于
Article.objects.filter()

all()返回的是一个包含该模型所有对象的QuerySet。我们可以在`all()`的基础上进一步链式过滤:

Article.objects.all().filter(published=True) 

all()对于获取某个模型的全部数据很有用。当然,如果数据量很大,我们可能需要限制返回的数据条数,以提高性能。另外,all()每次都会查询数据库。如果需要多次使用全部数据集,可以考虑使用缓存或预取相关对象:prefetch_related()。所以在合适的时候使用`all()`可以方便地获取模型的全部实例,但需要注意数据量大小和重复查询的问题。

4.delete()

delete()方法将删除QuerySet中的所有对象,并返回删除的对象数量。

  @action(detail=False, methods=['get','post'])
  def delete_example(self, request):
      name = request.data.get('name')
      # 删除名称为 'name' 的商品
      categories_to_delete = GoodsCategory.objects.filter(name=name)
      # 使用delete()方法删除对象
      deleted_count= categories_to_delete.delete()
      print(f"Deleted {deleted_count} categories.")      

主要流程是:1. 通过filter()筛选出需要删除的对象集合2. 在这个QuerySet上调用delete()方法实现删除3. delete()方法会删除QuerySet中的所有对象,并返回删除的对象数量所以delete()为批量删除QuerySet中的对象提供了很好的便利。注意delete()会立即执行删除操作,不像filter()那样是延迟执行。另外,delete()默认不会触发模型的delete()方法,如果需要调用可以设置:

categories_to_delete.delete(keep_parents=False)

这样会为每个对象调用delete()方法。delete()方法非常适合批量删除不需要的对象,可以用来定期清理数据库。但需要注意确保筛选条件正确,避免误删除。

5.update()

update() 方法将对QuerySet进行筛选,获取需要更新的对象集合,然后执行数据库更新操作。基本语法如下:

queryset.update(字段1=值1, 字段2=值2...)

这将设置指定的字段到相应的值。例如:

Article.objects.filter(published=True).update(status='p') 
# 将已发布文章的状态都设为'p'

Article.objects.filter(id__in=[1,2,3]).update(views=F('views') + 1)
# 对id为1,2,3的文章浏览量增1

update()默认只会更新指定的字段。需要注意,update()同样会立即执行更新,并返回更新的行数。update()提供了一个非常高效的批量更新对象方法,可以避免大量的单个对象更新开销。但同样需要确保更新条件的准确性。

6.create()

create() 方法是 save() 方法的快捷方式,用于创建并保存一个新的对象。

@action(detail=False, methods=['get','post'])
  def create_example(self, request):
      name = request.data.get('name')
          # 使用create()方法创建新的商品分类对象
      created_category = GoodsCategory.objects.create(name)
      print("Created category:", created_category) 

主要的用法是:

GoodsCategory.objects.create(name='名称', field1='值1',...)

这将实例化GoodsCategory,为其设置指定的字段值,然后直接保存到数据库中。与下面的用法等价:

category = GoodsCategory(name='名称', field1='值1',...) 
category.save()

所以create()方法对于快速创建对象非常方便,尤其是在数据初始化或者测试中可以减少代码量。需要注意:- create()参数必须提供对象必填字段的值
- create()会自动保存对象,无需再调用save()
- 创建成功后会返回新创建的对象实例综上,create()是save()方法的一个非常好用的封装,可以简化对象创建的代码。

7.count()

Django QuerySet 中的 count() 方法可以用来返回满足指定查询条件的对象的总数。count() 方法会执行查询,获取匹配查询(filters)的对象数目。使用方式:

Article.objects.filter(published=True).count() # 返回已发布文章数

Article.objects.filter(title__contains='Django').count() # 返回标题包含'Django'的文章数

Article.objects.filter(published=True).count() # 返回已发布文章数 Article.objects.filter(title__contains='Django').count() # 返回标题包含'Django'的文章数

count()会执行查询数据库的COUNT操作,性能上比提取所有对象再计算列表长度要更高效,尤其是数据量很大的时候。我们可以像链式调用filter()一样,链式调用count()来获取不同条件下的数量:

Article.objects.filter(published=True).filter(views__gt=10).count() 
# 返回已发布且浏览量大于10的文章数。

需要注意,使用count()之后再继续链式过滤就不会生效了。所以count()为我们提供了一个简单直观的方式来获取查询集大小。可以用来判断是否有匹配的对象,或者计算比较不同查询的结果数目。

8.order_by()

Django QuerySet 中order_by()方法用于对返回的对象进行排序。order_by()的常见用法:

# 按发布日期升序排序
Article.objects.order_by('publish_date') 

# 按浏览量降序排序 
Article.objects.order_by('-views')

# 先按发布日期降序,再按标题升序
Article.objects.order_by('-publish_date', 'title')

默认order_by()是按升序排列的,如果需要降序,可以在参数字段名前加一个负号-。可以传递多个字段名来先后进行排序,如上面的例子。order_by()通常用在需要排序的查询中,比如获取最新文章:

latest_articles = Article.objects.order_by('-publish_date')[:10] 

需要注意order_by()通常应该放在链式查询的最后,因为它会改变查询结果的顺序。order_by()非常实用,可以帮助我们按任意字段排序查询集,灵活地获取需要的数据。

9.values()

在Django中,values()方法可以用来获取QuerySet中的对象的指定字段的值,返回一个ValueQueryset,里面是以字典形式包含指定字段值的对象。那么

Map.objects.all().values().first()

的作用就是:

(1. Map.objects.all() 返回Map模型的全部对象的QuerySet

(2. 在这个QuerySet上调用`.values()`,不指定任何字段,那么会返回包含每个对象的所有字段及值的字典。

(3. 最后调用.first()返回第一个对象的字段字典。例如,如果Map模型有字段id, name, address,那么它类似于:

{
  'id': 1,
  'name': 'John',
  'address': '123 Main St' 
}

如果我们只需要名称和地址:

Map.objects.all().values('name', 'address').first()

那么得到的是:

{
  'name': 'John',
  'address': '123 Main St'
}

这可以避免提取整个对象然后访问字段,提高效率。所以values()方法非常适合只需要获取对象某些字段的值而不需要模型对象实例的时候使用。

 二、Instance

创建一个对象:Obj = Model(attr1=val1, attr2=val2),Obj.save()
更新一个对象:Obj = Model.objects.get(id=xxx),Obj.attr1 = val1,Obj.save()
删除一个对象:Obj = Model.objects.get(id=xxx),Obj.delete()

Django模型实例(Instance)表示的是数据库中一个模型对象的一行记录。它可以完成如下操作:

1. 创建对象实例可以通过Model类直接创建:

obj = Model(attr1=val1, attr2=val2)
obj.save()

或者使用objects管理器的create()方法:

obj = Model.objects.create(attr1=val1, ...)

2. 更新对象实例先获取实例,修改字段后保存:

obj = Model.objects.get(id=1) 
obj.attr1 = new_value
obj.save()

3. 删除对象实例获取实例后调用delete():

obj = Model.objects.get(id=1)
obj.delete()

所以Django模型实例表示单个对象,主要用于对象的CRUD操作。它和QuerySet的区别在于是一个对象 VS 一组对象。

QuerySet 适用于需要查找多个对象或进行聚合操作的场景,而 Instance 适用于单独对象的创建、修改和删除操作。

三、APIView(在 view.py 中)

 

 

APIview 是 Django REST Framework 提供的一个视图类。它和 Django 中的 view 类有些相似,但是又有一些不同之处。APIview 可以处理基于 HTTP 协议的请求,并返回基于内容协商的响应,它旨在提供一个易于使用且灵活的方式来构建 API 视图。

- APIView继承自Django的View类,提供了许多处理HTTP请求的方法,比如get、post等。

- APIView实现了内容协商,可以根据请求头中的Accept信息自动返回JSON或其他格式。

- APIView具有请求解析器,可以解析请求的数据,并将请求数据绑定到请求对象上。- APIView可以轻松地构建基于类的视图逻辑,通过继承和组合来重用通用逻辑。

- APIView支持基于函数的视图行为,可以使用@action装饰器来实现。

- APIView比Django的View类更偏向于构建Web API。它提供了对请求和响应的更多控制能力。

- APIView需要与序列化器Serializer配合使用,来序列化复杂数据。

总结起来,APIView是一个专门用来构建Web API的类,它建立在Django的通用View组件之上,提供了对requests和responses的控制,内容协商等功能,以及对Serializer的集成,可以更便捷地构建灵活的API。 

这里是一个使用APIView的代码示例:(可与项目给出的示例做对比补充)

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

class HelloView(APIView):

    def get(self, request):
        content = {'message': 'Hello, World!'}
        return Response(content)

    def post(self, request):
        name = request.data.get('name')
        content = {'message': 'Hello, {}!'.format(name)}
        return Response(content)

这个示例中定义了一个简单的HelloView,继承自APIView。

- get() 方法处理GET请求,返回一个字典作为响应数据。

- post() 方法处理POST请求,从请求数据中获取name参数,返回个性化的问候信息。

- APIView会自动根据请求方法调用对应的get或post方法。

- 返回Response对象,APIView会处理内容协商,转换数据格式。这样,就可以快速构建一个支持GET/POST的API端点了。我们还可以利用APIView提供的其他功能,比如解析器、身份验证等来构建更强大的API。APIView作为Django REST framework的基础,提供了简洁而不失灵活性的API视图构建方式。

# 面向对象编程
from django.shortcuts import render
from rest_framework.decorators import api_view
from .models import *
from rest_framework.response import Response
from rest_framework.views import APIView
#### APIView
 class GetGoods(APIView):
     def get(self, request):
         data = Goods.objects.all()
         serializer = GoodsSerializer(instance=data, many=True)
         print(serializer.data)
         return Response(serializer.data)

     def post(self, request):
         # 从请求数据中提取字段
         request_data = {
             "category": request.data.get("Goodscategory"),
             "number": request.data.get("number"),
             "name": request.data.get("name"),
             "barcode": request.data.get("barcode"),
             "spec": request.data.get("spec"),
             "shelf_life_days": request.data.get("shelf_life_days"),
             "purchase_price": request.data.get("purchase_price"),
             "retail_price": request.data.get("retail_price"),
             "remark": request.data.get("remark"),
         }

         # 使用 create() 方法创建新的商品对象
         new_goods = Goods.objects.create(**request_data)

         # 对创建的对象进行序列化,并作为响应返回
         serializer = GoodsSerializer(instance=new_goods)
         return Response(serializer.data)


 # 面向对象编程
 class FilterGoodsCategoryAPI(APIView):
     # request 表示当前的请求对象
     # self 表示当前实例对象

     def get(self, request, format=None):
         print(request.method)
         return Response('ok')

     def post(self, request, format=None):
         print(request.method)
         return Response('ok')

     def put(self, request, format=None):
         print(request.method)
         return Response('ok')

实现了一个简单的商品信息获取接口。主要逻辑是:

1. 从Goods模型中获取所有商品对象数据

2. 用GoodsSerializer序列化器对商品数据进行序列化

3. 将序列化后的数据通过Response返回这样就实现了一个获取所有商品信息的API端点。

需要注意的是:

- APIView会自动根据请求方法调用对应的方法处理器,如这里的get()来处理GET请求。

- 数据需要序列化后才能作为JSON响应返回,这里使用rest_framework的Serializer完成。

- Response包含了内容协商、状态码等响应处理功能。

使用APIView的优点是:

- 继承APIView就直接拥有了请求调度、响应处理等功能- 可以通过面向对象的方式组织视图逻辑,扩展灵活- 结合Serializer可以快速实现序列化与响应总之,这是一个典型的使用APIView构建API的示例,利用其提供的封装与便利性来简化视图开发。

def post(self, request):
         # 从请求数据中提取字段
         request_data = {
             "category": request.data.get("Goodscategory"),
             "number": request.data.get("number"),
             "name": request.data.get("name"),
             "barcode": request.data.get("barcode"),
             "spec": request.data.get("spec"),
             "shelf_life_days": request.data.get("shelf_life_days"),
             "purchase_price": request.data.get("purchase_price"),
             "retail_price": request.data.get("retail_price"),
             "remark": request.data.get("remark"),
         }

这个post方法实现了从请求数据中提取需要的参数来创建商品的功能。主要逻辑:

1. 从request.data中获取前端传来的各个字段的数据

2. 将获取到的数据保存到一个字典request_data中

3. request_data中的key就是模型的字段名,value是从请求中获取到的值

4. 这样就可以直接用这个request_data字典来创建商品实例:

goods = Goods.objects.create(**request_data)

这种字典参数的解包语法可以直接把字典的值赋给模型的对应字段。

5. 最后可能需要返回创建好的商品数据给前端:

serializer = GoodsSerializer(goods)
return Response(serializer.data)

这样,我们就可以通过接受用户输入的数据来创建新的商品,并返回结果。这种从请求中提取参数,然后直接解包传递的方式可以简化创建对象的代码。配合DRF的Serializer来序列化和响应数据,可以快速构建出创建对象的API。

# 面向对象编程
 class FilterGoodsCategoryAPI(APIView):
     # request 表示当前的请求对象
     # self 表示当前实例对象

     def get(self, request, format=None):
         print(request.method)
         return Response('ok')

     def post(self, request, format=None):
         print(request.method)
         return Response('ok')

     def put(self, request, format=None):
         print(request.method)
         return Response('ok')

实现了一个商品分类过滤的API视图,演示了APIView中如何根据不同的HTTP方法来处理不同的业务逻辑。

主要逻辑:

- 定义了FilterGoodsCategoryAPI类,继承APIView

- 分别实现了get(), post(), put()方法来处理不同的HTTP请求方法

- 在每个方法内部,打印了request.method,用于验证接收到的请求方法

- 然后直接返回字符串'ok'作为响应这样,当一个GET请求发送到这个视图的时候,会调用get()方法,并在终端打印输出“GET”。对于POST或PUT请求,也会分别调用对应的方法,并打印“POST”或“PUT”。APIView会自动根据请求方法将不同的请求分发到对应方法进行处理。我们可以在每个方法内实现真正的业务逻辑,比如获取分类、添加商品等。这种面向对象的类视图可以帮助我们更好地组织代码,利用APIView的请求分发来处理不同的请求与业务逻辑。

所以这是一个使用APIView的典型示例,演示了其根据请求方法调度到对应方法的功能。

未完待续

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

产品经理如何提高用户画像效果?SIKT模型

产品经理做用户画像,最担心被业务方反馈:没效果。这往往是由用户画像与业务场景脱节造成的。那么我们该如何从业务场景出发,让用户画像更有效?一般来说,我们可以采用SIKT模型解决这个问题。 用户画像 ​ 1、SIK…

kafka安装说明以及在项目中使用

一、window 安装 1.1、下载安装包 下载kafka 地址,其中官方版内置zk, kafka_2.12-3.4.0.tgz其中这个名称的意思是 kafka3.4.0 版本 ,所用语言 scala 版本为 2.12 1.2、安装配置 1、解压刚刚下载的配置文件,解压后如下&#x…

通过安全日志读取WFP防火墙放行日志

前言 之前的文档中,描写了如何对WFP防火墙进行操作以及如何在防火墙日志中读取被防火墙拦截网络通讯的日志。这边文档,着重描述如何读取操作系统中所有被放行的网络通信行为。 读取系统中放行的网络通信行为日志,在win10之后的操作系统上&am…

Monitor.Analog烧机室|高温老化箱软件概要设计

Monitor.Analog产品老化试验软件概要设计: 1. 引言: 模拟量采集软件的目标是实现对模拟量信号的采集、处理和展示。该软件旨在提供一个用户友好的界面,允许用户配置采集参数、实时监测模拟量信号,并提供数据分析和导出功能。 2. 功…

LVS-DR集群(一台LVS,一台CIP,两台web,一台NFS)的构建以及LVS-DR模式工作原理和特点

一.LVS-DR工作模式原理和特点 1.工作模式 2.模式特点 二.构建环境 1.五台关闭防火墙,关闭selinux,拥有固定IP,部署有http服务的虚拟机,LVS设备下载ipvsadm工具,NFS 设备需要下载rpcbind和nfs-utils 2.实现功能 3…

【简单认识Docker基本管理】

文章目录 一、Docker概述1、定义2.容器化流行的原因3.Docker和虚拟机的区别4.Docker核心概念 二、安装docker三、镜像管理1.搜索镜像2.下载(拉取)镜像3.查看已下载镜像4.查看镜像详细信息5.修改镜像标签6.删除镜像7.导出镜像文件和拉取本地镜像文件8.上传…

ruoyi-vue-pro yudao 项目报表设计器 积木报表模块启用及相关SQL脚本

目前ruoyi-vue-pro 项目虽然开源,但是report模块被屏蔽了,查看文档却要收费 199元(知识星球),价格有点太高了吧。 分享下如何启用 report 模块,顺便贴上sql相关脚本。 一、启用模块 修改根目录 pom.xml …

《安富莱嵌入式周报》第320期:键盘敲击声解码, 军工级boot设计,开源CNC运动控制器,C语言设计笔记,开源GPS车辆跟踪器,一键生成RTOS任务链表

周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版: https://www.bilibili.com/video/BV1Cr4y1d7Mp/ 《安富莱嵌入式周报》第320期:键盘敲击…

空洞卷积网络实现

代码中涉及的图片实验数据下载地址:https://download.csdn.net/download/m0_37567738/88235543?spm1001.2014.3001.5501 代码: import torch.nn as nn import numpy as npfrom matplotlib import pyplot as plt import time #from utils import get_ac…

【深入探究人工智能】:常见机器学习算法总结

文章目录 1、前言1.1 机器学习算法的两步骤1.2 机器学习算法分类 2、逻辑回归算法2.1 逻辑函数2.2 逻辑回归可以用于多类分类2.3 逻辑回归中的系数 3、线性回归算法3.1 线性回归的假设3.2 确定线性回归模型的拟合优度3.3线性回归中的异常值处理 4、支持向量机(SVM&a…

基于ArcGis提取道路中心线

基于ArcGis提取道路中心线 文章目录 基于ArcGis提取道路中心线前言一、生成缓冲区二、导出栅格数据三、导入栅格数据四、新建中心线要素五、生成中心线总结 前言 最近遇到一个问题,根据道路SHP数据生成模型的时候由于下载的道路数据杂项数据很多,所以导…

链表之第三回

欢迎来到我的:世界 该文章收入栏目:链表 希望作者的文章对你有所帮助,有不足的地方还请指正,大家一起学习交流 ! 目录 前言第一题:判断是否为环形链表第二题:找到两条链表的相交点第三题:返回…

webSocket 开发

1 认识webSocket WebSocket_ohana!的博客-CSDN博客 一,什么是websocket WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议)它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽…

【机器学习】— 2 图神经网络GNN

一、说明 在本文中,我们探讨了图神经网络(GNN)在推荐系统中的潜力,强调了它们相对于传统矩阵完成方法的优势。GNN为利用图论来改进推荐系统提供了一个强大的框架。在本文中,我们将在推荐系统的背景下概述图论和图神经网…

回归预测 | MATLAB实现PSO-RBF粒子群优化算法优化径向基函数神经网络多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现PSO-RBF粒子群优化算法优化径向基函数神经网络多输入单输出回归预测(多指标,多图) 目录 回归预测 | MATLAB实现PSO-RBF粒子群优化算法优化径向基函数神经网络多输入单输出回归预测(多指标,多图&a…

matlab使用教程(19)—曲线拟合与一元方程求根

1.多项式曲线拟合 此示例说明如何使用 polyfit 函数将多项式曲线与一组数据点拟合。您可以按照以下语法,使用 polyfit 求出以最小二乘方式与一组数据拟合的多项式的系数 p polyfit(x,y,n), 其中: • x 和 y 是包含数据点的 x 和 y 坐标的向量 …

深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)

深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)。 一、简介 单点登录(Single Sign On),简称为 SSO。 它的解释是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 ❝ 所谓一次登录,处处登录。同样一处退出,处处退出。 ❞ 二…

Axios使用CancelToken取消重复请求

处理重复请求:没有响应完成的请求,再去请求一个相同的请求,会把之前的请求取消掉 新增一个cancelRequest.js文件 import axios from "axios" const cancelTokens {}export const addPending (config) > {const requestKey …

时序预测 | MATLAB实现基于CNN-BiGRU卷积双向门控循环单元的时间序列预测-递归预测未来(多指标评价)

时序预测 | MATLAB实现基于CNN-BiGRU卷积双向门控循环单元的时间序列预测-递归预测未来(多指标评价) 目录 时序预测 | MATLAB实现基于CNN-BiGRU卷积双向门控循环单元的时间序列预测-递归预测未来(多指标评价)预测结果基本介绍程序设计参考资料 预测结果 基本介绍 MATLAB实现基于…

Vs code 使用中的小问题

1.Java在Vs code 中使用单元测试失败或者如何使用单元测试 创建Java项目,或者将要测试的文件夹添加进工作区 要出现lib包,并有两个测试用的jar包 编写测试文件 public class TestUnit{ public static void main(String[] args) {String str "…