后端项目技术栈
Django工程逻辑
Django 是一个高级的 Python Web 框架,它鼓励快速开发和干净、实用的设计。Django 遵循 MTV(Model-Template-View)设计模式,这是 MVC(Model-View-Controller)的一个变种。下面是 Django 工程逻辑的详细介绍:
1. 模型(Models)
- 数据模型:定义应用程序的数据结构,通常在
models.py
文件中以类的形式存在。- ORM(Object-Relational Mapping):Django 的 ORM 允许你使用 Python 代码来操作数据库,无需编写 SQL 语句。
- 迁移系统:Django 提供了一个迁移系统来管理数据库的变化,如创建、修改和删除数据库结构。
2. 视图(Views)
- 业务逻辑:视图包含业务逻辑,处理用户的输入,执行数据库操作,并返回相应的响应。
- 请求和响应:视图接收
HttpRequest
对象作为输入,并返回HttpResponse
对象作为输出。- 函数视图 vs 类视图:Django 支持函数视图和基于类的视图(Class-Based Views, CBVs),后者提供了更多重用和扩展的选项。
3. 模板(Templates)
- 动态内容渲染:模板是 HTML 文件,可以包含动态内容。Django 模板语言允许你在模板中插入变量和标签。
- 继承和包含:Django 模板支持继承和包含,方便创建可重用的模板组件。
4. 路由(URLconf)
- URL 分发:Django 使用 URLconf(URL configuration)来映射 URL 到视图函数。
- 正则表达式 vs 路径:从 Django 2.0 开始,推荐使用路径(path)来定义 URL 模式,它是对正则表达式的更易读的替代。
5. 表单(Forms)
数据输入:表单用于收集用户输入,Django 提供了一个强大的表单系统来处理输入验证和渲染。
表单类:可以定义自己的表单类,继承自
forms.Form
或forms.ModelForm
。
6. 管理后台(Admin)
- 自动化管理界面:Django 内置了一个强大的管理后台,可以通过注册模型自动生成管理界面。
- 定制化:可以定制管理后台的外观和行为,以适应不同的需求。
7. 中间件(Middleware)
- 请求/响应处理:中间件是全局的处理器,可以处理请求和响应。它们在视图之前和之后执行。
8. 静态文件和媒体文件
- 静态文件:Django 提供了一个系统来管理静态文件,如 CSS、JavaScript 和图片。
- 媒体文件:用户上传的文件(如图片、文档)被称为媒体文件,Django 允许你配置媒体文件的存储和访问。
9. 测试框架
- 自动化测试:Django 内置了一个测试框架,允许你编写单元测试来验证你的代码。
10. 国际化和本地化
- i18n:Django 支持国际化(i18n)和本地化(l10n),可以轻松创建多语言网站。
django工程为什么加跨域corsheaders.middleware.CorsMiddleware?
在 Django 工程中加入
CorsMiddleware
主要是出于处理跨域资源共享(CORS, Cross-Origin Resource Sharing)问题的需要。CORS 是一种安全机制,它允许或限制网页从另一个域名加载资源。通过加入CorsMiddleware
,你的 Django 工程可以更安全、更灵活地处理来自不同源的请求,这对于构建现代 web 应用来说是非常重要的。正确配置 CORS 策略可以确保你的 API 既安全又易于与前端应用集成。
什么是REST?
REST,全称为Representational State Transfer(表现层状态转移),是一种软件架构风格,用于设计网络应用程序。它由Roy Fielding博士在2000年的博士论文中提出,旨在通过使用标准的HTTP方法来简化分布式系统的交互。REST架构风格的核心原则包括:
- 客户端-服务器架构:客户端和服务器之间通过请求-响应模式进行通信,服务器提供资源,客户端通过请求来获取资源。
- 无状态:每个请求从客户端到服务器必须包含理解请求所需的所有信息,服务器不会存储任何会话信息。这意味着每个请求都是独立的,服务器不需要记住之前的请求状态。
- 可缓存:数据被标记为可缓存或不可缓存。如果可以缓存,客户端可以存储数据的副本,减少后续请求的延迟。
- 统一接口:服务器通过统一的接口处理资源,客户端通过这个接口与服务器交互。这有助于降低系统的复杂性,并提高系统的可伸缩性。
- 分层系统:通信可以在多个层次上进行,客户端通常不知道它是否直接与服务器通信,或者中间是否有代理服务器。
- 按需代码(可选):服务器可以向客户端发送代码,客户端可以执行这些代码来增强其功能。
在REST架构中,资源通过URI(统一资源标识符)进行标识,通常是一个URL。HTTP方法用于定义对资源的操作,常见的HTTP方法包括:
- GET:用于获取资源。
- POST:用于创建新资源。
- PUT:用于更新现有资源。
- DELETE:用于删除资源。
- PATCH:用于对资源进行部分更新。
RESTful API(应用程序编程接口)是遵循REST原则的API。它们通常易于使用,因为它们依赖于标准的HTTP方法和状态码,这使得它们与各种客户端和服务器技术兼容。RESTful API广泛应用于Web服务和移动应用程序,因为它们提供了一种简单、灵活的方式来访问和操作数据。
django工程为什么要序列化?
在 Django 工程中,序列化通常通过使用 Django REST framework(DRF)来实现。序列化是一个将数据结构或对象状态转换为可存储或可传输的格式的过程。在 Web 开发中,序列化通常指的是将复杂的数据类型(如 Django 的 QuerySets 或模型实例)转换为 JSON 或 XML 等格式,以便客户端(如 Web 浏览器或移动应用)可以轻松地使用这些数据。以下是 Django 工程中序列化的几个主要原因:
- API 响应:在构建 Web API 时,需要将数据库中的数据以结构化的格式(如 JSON)返回给客户端。序列化将模型实例转换为 JSON 对象,从而控制 API 的输出格式。
- 数据传输:在分布式系统或微服务架构中,服务之间需要通过网络传输数据。序列化数据可以确保数据在不同服务之间传输时保持一致性和完整性。
- 前端消费:现代 Web 应用通常使用 JavaScript 来处理前端逻辑。序列化数据使得前端代码可以轻松地解析和使用从服务器接收的数据。
- 数据持久化:在某些情况下,可能需要将数据保存到文件或缓存中。序列化可以将数据转换为文本格式,便于存储和检索。
- 简化复杂数据结构:序列化可以将复杂的数据结构(如包含关联对象的 Django 模型)简化为更易于处理的格式,如列表或字典。
- 兼容性:不同的系统和平台可能使用不同的数据表示方法。序列化数据可以确保数据在不同系统之间传输时的兼容性。
- 安全性:通过序列化,可以确保只传输必要的数据字段,避免敏感信息的泄露。
- 性能优化:序列化可以减少网络传输的数据量,因为可以只序列化所需的数据字段,而不是整个对象。
插值算法
'''
这三种插值算法分别是:
1. LinearNDInterpolator:
- 算法原理:线性 N 维插值,用于在 N 维空间中进行插值。它基于多边形分段线性插值,使用 N 维空间中的数据点来估计给定点的值。
- 优点:简单且高效,适用于数据点密集的情况。
- 缺点:当数据点分布不均匀或存在噪声时,可能会产生较大的误差。
2. NearestNDInterpolator:
- 算法原理:最近邻 N 维插值,用于在 N 维空间中找到距离最近的点,并使用该点的值作为插值结果。
- 优点:易于实现且计算速度快,适用于数据点分布不规则的情况。
- 缺点:可能会导致插值结果不够平滑,特别是在数据点密集的情况下。
3. CloughTocher2DInterpolator:
- 算法原理:Clough-Tocher 二维三次插值,用于二维空间中的插值。它基于三角形网格,利用给定的节点值进行插值计算。
- 优点:能够产生平滑的插值结果,适用于二维数据的插值需求。
- 缺点:计算量较大,需要构建三角形网格进行插值,可能不适用于高维数据的插值任务。
这三种插值算法在不同情况下有各自的优劣势,选择合适的插值算法取决于数据的特点、插值精度的要求以及计算资源的限制。
'''
def fun_interp_data1(self):
# 线性 N 维插值
# 创建 LinearNDInterpolator 对象
interp = LinearNDInterpolator(np.vstack((self.x, self.y)).T, self.z)
# 定义网格点用于绘图
self.x_grid, self.y_grid = np.meshgrid(np.linspace(min(self.x), max(self.x), 150),
np.linspace(min(self.y), max(self.y), 100))
# 进行插值
z_interp = interp(self.x_grid.flatten(), self.y_grid.flatten())
z_interp = z_interp.reshape(self.x_grid.shape)
# 如果z_interp里面值有大于60的,那么把值改成65
self.z_interp = np.where(z_interp > 65, 65, z_interp)
interpolated_data = {
'x': np.round(self.x_grid, 2).tolist(),
'y': np.round(self.y_grid, 2).tolist(),
'z': np.round(self.z_interp, 2).tolist()
}
return interpolated_data
def fun_interp_data2(self):
# 最近邻 N 维插值
# 创建 NearestNDInterpolator 对象
self.interp = NearestNDInterpolator(np.vstack((self.x, self.y)).T, self.z)
# 定义网格点用于绘图
self.x_grid, self.y_grid = np.meshgrid(np.linspace(min(self.x), max(self.x), 150),
np.linspace(min(self.y), max(self.y), 100))
# 进行插值
z_interp = self.interp(self.x_grid.flatten(), self.y_grid.flatten())
z_interp = z_interp.reshape(self.x_grid.shape)
# 如果z_interp里面值有大于60的,那么把值改成65
self.z_interp = np.where(z_interp > 65, 65, z_interp)
self.pl_data_count = self.z_interp.size
interpolated_data = {
'x': np.round(self.x_grid, 2).tolist(),
'y': np.round(self.y_grid, 2).tolist(),
'z': np.round(self.z_interp, 2).tolist()
}
return interpolated_data
def fun_interp_data3(self):
# Clough-Tocher 二维三次插值
# 创建 CloughTocher2DInterpolator 对象
self.interp = CloughTocher2DInterpolator(points=np.column_stack((self.x, self.y)), values=self.z)
# 定义网格点用于绘图
self.x_grid, self.y_grid = np.meshgrid(np.linspace(min(self.x), max(self.x), 150),
np.linspace(min(self.y), max(self.y), 100))
# 进行插值
z_interp = self.interp(self.x_grid, self.y_grid)
# 如果z_interp里面值有大于60的,那么把值改成65
self.z_interp = np.where(z_interp > 65, 65, z_interp)
self.pl_data_count = self.z_interp.size
interpolated_data = {
'x': np.round(self.x_grid, 2).tolist(),
'y': np.round(self.y_grid, 2).tolist(),
'z': np.round(self.z_interp, 2).tolist()
}
return interpolated_data