当前位置: 首页 > news >正文

Django创建应用、ORM的进阶使用及模型类数据库迁移

1 Django项目创建第一个应用

Django 项目就是基于 Django 框架开发的 Web 应用,它包含了一组配置和多个应用,我们把应用称之为 App,在前文中对它也做了相应的介绍,比如 auth、admin,它们都属于 APP。

一个 App 就是一个 Python 包,通常一个 App 可以包含模型、视图、模板和 URL 配置文件,可以被应用到多个 Django 项目中,因为它们的本质就是可被重用的 Python 软件包。

1.1 创建应用

Django 的设计目标是让开发者关注应用的功能逻辑的实现。

所以,创建应用的过程是非常简单的,利用 manage.py 提供的 startapp 命令就可以创建一个APP。

具体命令如下所示:

# 语法
# python manage.py startapp 应用名
python manage.py startapp index

startapp 同样也属于 manage.py 的子命令,用来创建 Django 的应用。

执行这个命令不会在命令行看到任何输出,但是可以在 manage.py 的同级目录下看到多出了一个 index 目录:

我们对这些文件做逐一的解释:

  • admin.py 用于将 Model 定义的数据表注册到管理后台,是 Django Admin 应用的配置文件

  • apps.py 用于应用程序本身的属性配置文件

  • models.py 用于定义应用中所需要的数据表

  • tests.py 文件用于编写当前应用程序的单元测试

  • views.py 用来定义视图处理函数的文件

  • 一级目录下的 __init__.py 文件标识 index 应用是一个 Python 包

  • migrations 目录用于存储数据库迁移时生成的文件,该目录下的 __init__.py 文件标识 migrations 是一个 Python 包

这就是 index 应用涉及到的所有文件,当然在实际的开发工作中,该应用目录下的文件也不是一成不变的,开发者根据自己的需要会相应的增加文件或者子目录,比如 urls.py 文件或者存储静态文件的 static 目录等。所以大家千万不要认为 Django 框架自动生成的目录,无需我们做其他操作或者更改,这是使用 Django 的一个误区。

1.2 应用的添加

应用创建完成后,我们还需要在 settings.py 配置文件中对其进行添加。

我们已经对 INSTALLED_APPS 做了介绍,把我们创建的应用添加到这个列表,如下所示:

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

用如上方式添加完成后,就可以让 index 应用的和整个项目融为一体了。

接下来,就可以正式进入开发应用阶段了,通过实现一些小的功能点,让我们更加全面的了解 Django 框架。

2 Django ORM进阶应用

ORM (Object Realtional Mapping)即对象关系映射,它是一种基于关系型数据库的程序技术。ORM 允许你使用类和对象对数据库进行操作,这大大提高了对数据库的控制,避免了直接使用 SQL 语句对数据库进行操作。这种程序技术的底层主要是通过映射机制实现的,有兴趣的可以自己研究一下!

Web 开发中对数据库的操作是必不可少的,然而每种数据库的操作方式以及用法不尽相同。由于 Django 中 ORM 的存在,为我们操作不同种类的数据库提供了统一的方法,ORM 适配了多种常用的关系型数据库,例如 PostgreSQL、MySQL、Oracle、Sqlite3 等。

2.1 Django中定义数据表

那么在 Django 中如何使用 ORM 模块来定义一张数据表呢?

在定义数据表之前,我们应该首先理解什么是模型类。

  • 模型类

    其实模型类本质上属于一个 Python 类,只不过在 Django 中称之为做模型类 ,它是由 django.db.models.Model 派生出的子类

    通过上述介绍,我们可以这样理解:Django 中模型类就相当于 ORM 模块。

  • 定义数据表

    现在有一张用户信息表 UserInfo,它有两个字段 name 和 password,可以定义如下:

    class UserInfo(models.Model):name = models.CharFiled(max_length=100)password = models.CharFiled(max_length=100)

通过以上代码,UserInfo 数据表就已经创建完成,我们对代码进行逐行解析:

  • 第 1 行,使用 from django.db import models 导入 models 模块

    • 第 2 行,使用 class 关键字对 UserInfo 表进行类定义,并继承了models 模块中的 Model 类

    • 第3、4 行,数据表中的字段 name 和 password 是 UserInfo 类的属性,name 和 password 字段类型都是 CharFiled,字段长度均是100。

2.2 ORM定义项目数据表

下面我们用 ORM 定义 index 应用所需的数据表,首选找到 index 应用下的 models.py 文件。

在文件里添加如下代码:

from django.db import models
​
​
# Create your models here.
​
​
# 创建book表
class Book(models.Model):title = models.CharField(max_length=30, unique=True, verbose_name='书名')public = models.CharField(max_length=50, verbose_name='出版社')price = models.DecimalField(max_digits=7, decimal_places=2, verbose_name='定价')retail_price = models.DecimalField(max_digits=7, decimal_places=2, verbose_name='零售价', default="30")
​def __str__(self):return "title:%s pub:%s price:%s" % (self.title, self.public, self.price)
​
​
# 创建作者表
class Author(models.Model):  name = models.CharField(max_length=30, verbose_name='姓名')email = models.EmailField(verbose_name='邮箱')
​def __str__(self):return '作者:%s' % self.name
​
​
# 创建用户信息表
class UserInfo(models.Model):  username = models.CharField(max_length=24, verbose_name='用户注册')password = models.CharField(max_length=24, verbose_name='密码')

通过上述代码,我们定义了一个名叫 Book 的数据表。

数据表由以下字段构成书名(title)、出版社(public)、价格(price)、零售价(retail_price),而且对每个字段都做添加了相应的字段属性以及字段选项。

2.3 Filed的通用字段选项

Model 中添加的字段都是 Field 类型的实例,不同的 Field 类型可能会支持不同的字段选项,但是也有很多字段选项是通用的,即可以用在任何一种 Field 类型中。这里介绍一些常用且重要的通用字段选项,它们都有对应的默认值,这些字段选项都是可选的,理解这些有助于更好地使用它们。

  • blank

    默认值是 False,设置为 True 时,字段可以为空。设置为 False 时,字段是必须填写的。如果是字符型字段 CharField 和 TextField,它们是用空字符串来存储空值的。

  • unique

    默认值是 False,它是一个数据库级别的选项,规定该字段在表中必须是唯一的。

  • null

    默认为 False,如果此选项为 False 建议加入 default 选项来设置默认值。如果设置为 True,表示该列值允许为空。日期型、时间型以及数字型字段不接受空字符串。所以当设置 IntegerField,DateTimeField 型字段可以为空时,需要将 blank 与 null 均设为 True 才可以。

  • db_index

    默认值是 False,如果设置为 True,Django 则会为该字段创建数据库索引,如果该字段经常作为查询的条件,那么就需要设置 db_index 选项,从而加快数据的检索速度。

  • db_column

    这个选项用于设置数据库表字段的名称。如果没有指定,Django 默认使用 Model 中字段的名字。

  • default

    用于给字段设置默认值,该选项可以设置为一个值或者是可以调用对象,但不能是可变对象,不同字段类型默认值也不同,比如 BooleanFiled 布尔类型 default 值为Ture 或者 False。主要的使用场景是当一个字段的值被用户省略时,后台服务器自动为该字段的设置默认值。

  • primary_key

    默认值是 False,如果设置为 True,表示该字段为主键,在 Django 中 默认 id 为主键,也就是说即使你的数据表中没有创建 id 字段,Django 也会自动为你创建 id 字段并将其设置为主键。如果你在表中设置了其他字段为主键的时,那么 Django 将取消为 id 字段设置主键。

  • choices

    这个选项用于给字段设置可以选择的值。它是一个可迭代对象,即列表或者元组,其中每一个元素都是一个二元组(a,b)的形式,a 是用来选择的对象,b 是对 a 的描述信息。比如我们对某个人性别定义数据表如下所示:

    # 创建表
    class UserInfo(models.Model):# 定义chocies参数的对应关系,以元组(或者列表)的形式进行表述:choices = ((male, '男性'),(female, '女性'),)gender = models.CharField(max_length=2,choices = choices,default='male')

  • verbose_name

    设置此字段在 admin 后台管理系统界面上的显示名称,如果没有设置这个字段,Django 将会直接展示字段名并且将字段中的下划线转变为空格。

3 index应用数据库迁移

上面我们创建好了 index 应用所需的数据表,下一步就是执行数据库的迁移,之后让我们再来看一下又有什么新的变化发生呢?数据库迁移的两个命令分步骤执行,如下所示:

python manage.py makemigrations
python manage.py migrate

执行完毕后会在命令行得到如下输出:

若迁移过程中出现报错提示,首先检查您的 models.py 文件是否正确书写,除此之外,也可能由于 Django 与 MySQL 版本问题导致报错。

从上述输出结果可以看出,我们对 index 应用进行了数据库迁移工作。

并且在数据库中创建了三张表,分别是 Author、Book、UserInfo。

而且在 index 应用下的 migrations 目录下生还成了一个 0001_initial.py 的文件:

这个迁移文件包含了创建数据表时用到的所有信息,这是一个临时的过度文件。

4 魔术方法__str__

__str__方法是 Python 中的 "魔术” 方法,它是为 print 这样的打印函数设计的,它属于 python 的 object 基类的一个方法,也就是说 python 所有的类都有该方法,当然 Django 的 modle 类也有。如果没有这个方法定义,打印对象会显示对象的内存地址,但是这样的显示方式不够友好,且不利于调试,而用 __str__ 方法后,可以在 print 时得到易于人阅读的信息,在如下所示:

# 直接print打印
class TestClass:def __init__(self):self.name = 'testcase't = TestClass() #实例化对象
print(t)        # 结果显示:<__main__.TestClass object at 0x8f5c27b42367>
# __str__方法
class TestClass:def __init__(self):self.name = '小明'def __str__(self):return self.name
t = TestClass() #实例化对象
print(t)      # 结果显示:小明
 

本节内容为 index 应用创建了数据表,并且一步步带领大家实现了如何自定义模型类以及完成了数据表的迁移的,而且对产生的迁移文件也做了介绍,接下来我们将学习 Django 的后台管理系统,看看它是如何配合 ORM 使用的。

5 Django Admin数据表可视化

Django 的后台管理系统是非常出色的,新建项目以后,Django 就为我们设置好了后台管理系统的各种功能。

5.1 后台管理系统的重要性

我们知道,Web 站点上某些内容的改动是后台管理员来完成的,如果管理员直接用 Shell 或者 SQL 语句来修改,不仅麻烦,而且容易操作失误,从而导致数据不一致的结果。假如是一个不懂编程的人呢?应该怎么去操作呢?上述问题,说明了构建一个后台管理系统的重要性,通过后台管理系统为管理员提供一种便捷有效的操作方式。

后台管理系统主要是对数据表的存储做专门的管理,例如针对微博或者论坛类的站点,管理员需要删除不合规的文章,或者公司内部需要发布新的话题等,这些都是通过数据表的管理实现的。单一功能的后台系统比较容易构建,但是如果功能增多情况下,就需要对多个数据表做管理,这就增加了开发人员的重复性工作。Django 提供的后台管理系统很好的解决了这个问题。

5.2 创建超级用户

通过命令创建超级管理员账户,命令如下所示:

python manage.py createsuperuser --username=admin --email=admin@163.com

这里将用户名设置为 admin,邮箱设置为 admin@163.com,也可以根据自己的需要去修改。如果在 createsuperuser 后面不加任何内容,Django 会提示用户输入用户名和邮箱。当前命令执行后,需要重复输入两次密码,密码可以根据自己的需要设置,但是密码不能过于简单。

如下图所示,表示创建成功:

注意:输入密码的时候,不会显示。

注意:超级用户拥有所有权限,方便技术人员或非技术人员以可视化的形式对应用数据记录实现增删改查的操作。

启动 BookStore 项目,然后在浏览器地址栏输入 127.0.0.1:8000/admin 访问,输入刚刚创建的超级用户名以及密码进行登录。如下所示登录成功:

5.3 将Model注册到管理后台

  • 在admin.py文件中声明

    那么如何把自定义的数据表 Model 注册到管理后台呢?

    也就是说要把 Model 显示在 Admin 后台管理系统界面,需要做哪些操作呢?

    当我们使用 startapp 命令创建 index 应用的时候会自动创建 admin.py 文件,想要把自定义的 Model 注册到管理后台,就需要在 admin.py 文件中进行声明,添加如下代码:

    from django.contrib import admin #Django自动在admin.py文件中导入
    from index.models import Book, Author,UserInfo #这个需要我们自己导入相应的模型类(数据表)
    admin.site.register([Book,Author,UserInfo])

    通过上述代码,我们就完成了将 Model 注册到后台管理系统的操作,其实实现的过程也非常的简单,首先通过 django.contrib 的标准库引入 admin 应用,然后把 index 应用下我们自定义的三张数据表引入,最后我们调用 admin.site.register() 方法实现模型类的注册。多个模型类一起注册我们使用列表的形式来统一注册,如果是单一的模型类注册,我们可以使用以下方式即可:

    admin.site.register(Book)

    至此我们就完成了数据表在 Admin后台管理系统的可视化操作,我们再次使用ctrl+F5刷新后台管理系统的显示页面,可以得到如下结果:

  • 提示:图中每张数据表的名字都加上了s,这是Django自动设定的,我们可以通过相应的修改将其去掉,在后续章节我们将介绍。

    虽然看似页面简单并且没有太多的附加功能,但是对于简单的增删改操作而言已经足够使用了。我们打开其中的 UserInfos 数据表来查看,如下所示:

  • 点击增加 USERI INFO 按钮会得到如下页面,在此页面我们可以进行数据的添加、编辑、保存操作:

相关文章:

Django创建应用、ORM的进阶使用及模型类数据库迁移

1 Django项目创建第一个应用 Django 项目就是基于 Django 框架开发的 Web 应用&#xff0c;它包含了一组配置和多个应用&#xff0c;我们把应用称之为 App&#xff0c;在前文中对它也做了相应的介绍&#xff0c;比如 auth、admin&#xff0c;它们都属于 APP。 一个 App 就是一…...

tcpdump 如何使用

tcpdump 是一个在Unix和类Unix系统上运行的网络抓包工具&#xff0c;它用于捕获网络流量并将其转储到文件中以供后续分析。tcpdump非常强大&#xff0c;可以用于监控、调试和分析网络通信&#xff0c;用于排查网络问题以及安全审计。以下是关于如何使用tcpdump的详细介绍&#…...

goweb入门

创建gomod项目 go mod init web01新建main.go package mainimport ("fmt""net/http" )func handler(writer http.ResponseWriter, request *http.Request) {fmt.Fprintf(writer, "Hello World,%s!", request.URL.Path[1:]) } func main() {fmt…...

【python爬虫】批量识别pdf中的英文,自动翻译成中文下

不管是上学还是上班,有时不可避免需要看英文文章,特别是在写毕业论文的时候。比较头疼的是把专业性很强的英文pdf文章翻译成中文。我记得我上学的时候,是一段一段复制,或者碰到不认识的单词就百度翻译一下,非常耗费时间。之前的文章提供了批量识别pdf中英文的方法,详见【…...

YApi 新版如何查看 http 请求数据

YApi 新版如何查看 http 请求数据 因chrome 安全策略限制&#xff0c;在 cross-request 升级到 3.0 后&#xff0c; 不再支持文件上传功能&#xff0c;并且需要通过以下方法查看 network:1.首先在chrome 输入 > chrome://extensions打开扩展页2.开启开发者模式3.点击 cross…...

自动驾驶(apollo)

&#x1f493;博主csdn个人主页&#xff1a;小小unicorn &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &#x1f339;&#x1f339;&#x1f339;关注我带你学习编程知识 自动驾驶技术 引言自动驾驶的基本原理自动驾驶的技术挑战自动驾驶的潜在影响结…...

web3.0涉及的技术

非同质化代币 非同质化代币&#xff08;Non-Fungible Tokens&#xff0c;NFTs&#xff09;是一种数字资产&#xff0c;与传统的加密货币&#xff08;如比特币或以太币&#xff09;不同&#xff0c;它们具有独特性和不可替代性。NFTs 是基于区块链技术的数字资产&#xff0c;用…...

26. 不相同的字符串(第一期模拟笔试)

题目&#xff1a;样例&#xff1a; 输入 1 abab 输出 2 思路&#xff1a; 这里的题目要求我们要最少操作删除次数&#xff0c;我们可以先统计每个字符个数&#xff0c;然后开始删除&#xff0c;每操作删除一次&#xff0c;就会产生一个新字符&#xff0c;ans r[i] >> 1…...

Rethink LSTMGRU

LSTM 设计思想 姑且不看偏置。 W W W 和 U U U 是加权的矩阵&#xff0c;写模型的时候用 nn.Linear(in_dim, out_dim) 就成&#xff1b; σ \sigma σ 是 Sigmoid 函数 第一条&#xff0c;遗忘门&#xff0c;定义为 有多少内容需要被遗忘&#xff1b;第二条&#xff1a;输入门…...

状态管理艺术——借助Spring StateMachine驭服复杂应用逻辑

文章目录 1. 什么是状态2. 有限状态机概述3. Spring StateMachine4. Spring StateMachine 入门小案例4.1 接口测试 5. 总结 1. 什么是状态 在开发中&#xff0c;无时无刻离不开状态的一个概念&#xff0c;任何一条数据都有属于它的状态。 比如一个电商平台&#xff0c;一个订…...

获取和设置小程序和h5的页面栈

获取页面栈&#xff1a; 语法&#xff1a; let pages getCurrentPages(); 设置页面栈&#xff1a; 小程序语法&#xff1a; pages.data H5语法&#xff1a; pages let pages getCurrentPages(); let page pages[pages.length - 2]; if(page.route "pages/conf…...

Mysql基于成本选择索引

本篇文章介绍mysql基于成本选择索引的行为&#xff0c;解释为什么有时候明明可以走索引&#xff0c;但mysql却没有走索引的原因 mysql索引失效的场景大致有几种 不符合最左前缀原则在索引列上使用函数或隐式类型转换使用like查询&#xff0c;如 %xxx回表代价太大索引列区分度过…...

Element-ui container常见布局

1、header\main布局 <template> <div> <el-container> <el-header>Header</el-header> <el-main>Main</el-main> </el-container> </div> </template> <style> .el-header { …...

ssm实现折线统计图

​ 方法1&#xff1a;单张数据表中的数据图表生成 图表统计&#xff0c;查看部门人数统计这里实现的时单张表中的数据实现部门人数折线统计图展示。 <script type"text/javascript">// 利用AjAx来获取后台传入的数据&#xff08;Responsebody注解传入的&…...

GLSL ES着色器 精度限定字

目录 前言 WebGL支持的三种精度 数据类型的默认精度 float类型没有默认精度 预处理指令 在GLSL ES中常用的三种预处理指令。 预定义的内置宏 前言 GLSL ES新引入了精度限定字&#xff0c;目的是帮助着色器程序提高运行效率&#xff0c;削减内存开支。顾名思义&#xf…...

webrtc的FULL ICE和Lite ICE

1、ICE的模式 分为FULL ICE和Lite ICE&#xff1a; FULL ICE:是双方都要进行连通性检查&#xff0c;完成的走一遍流程。 Lite ICE: 在FULL ICE和Lite ICE互通时&#xff0c;只需要FULL ICE一方进行连通性检查&#xff0c; Lite一方只需回应response消息。这种模式对于部署在公网…...

flink的几种常见的执行模式

背景 在运行flink时&#xff0c;我们经常会有几种不同的执行模式&#xff0c;比如在IDE中启动时&#xff0c;通过提交到YARN上&#xff0c;还有通过Kebernates启动时&#xff0c;本文就来记录一下这几种模式 flink的几种执行模式 flink嵌入式模式&#xff1a; 这是一种我们在…...

蓝桥杯备赛Day8——队列

大家好,我是牛哥带你学代码,本专栏详细介绍了蓝桥杯备赛的指南,特别适合迎战python组的小白选手。专栏以天作为单位,定期更新,将会一直更新,直到所有数据结构相关知识及高阶用法全部囊括,欢迎大家订阅本专栏! 队列也属于基础数据结构。 队列概念 队列是一种数据结构,…...

用滑动条做调色板---cv2.getTrackbarPos(),cv2.creatTrackbar()

滑动轨迹栏作调色板 cv.createTrackbar(‘R’, ‘image’, 0, 255, nothing) 参数&#xff1a;哪个滑动轨迹栏&#xff0c;哪个窗口&#xff0c;最小值&#xff0c;最大值&#xff0c;回调函数 cv.getTrackbarPos(‘R’, ‘image’) 参数&#xff1a;轨迹栏名&#xff0c;窗口…...

dubbo 服务注册使用了内网IP,而服务调用需要使用公网IP进行调用

一、问题描述&#xff1a; 使用dubbo时&#xff0c;提供者注册时显示服务地址ip为[内网IP:20880]&#xff0c;导致其他消费者在外部连接的情况下时&#xff0c;调用dubbo服务失败 二、解决办法 方法一、修改hosts文件 &#xff08;1&#xff09;. 先查询一下服务器的hostna…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...