Django 和 Vue3 前后端分离开发笔记
前后端分离开发
前后端分离开发是一种网页应用设计模式,前端请求的响应不再是一个个(带模板语法的)html
文件,而是需要的数据
,例如Django充当后端处理请求返回数据库的数据,Vue作为前端负责处理界面的搭建
Django Ninja API
Django Ninja 是一个用于使用 Django 和 Python 3.6+ 类型提示构建 API 的网络框架。它具有以下主要特点:
- 简单易懂:设计为易于使用和符合直觉,适合快速上手。
- 快速执行:多亏了 Pydantic 和异步支持,具有非常高的性能。
- 快速编程:类型提示和自动文档生成让开发者只需关注业务逻辑。
- 基于标准:基于 OpenAPI(以前称为 Swagger)和 JSON 模式。
- 对 Django 友好:与 Django 核心和 ORM 有良好的集成。
- 可用于生产:被多家公司用于实际项目,稳定可靠。
创建和使用 NinjaAPI
-
安装 Django Ninja:
pip install django-ninja
-
创建 Django 项目(如果还没有):
django-admin startproject apidemo cd apidemo
-
在
urls.py
中配置 API:# apidemo/urls.py from django.contrib import admin from django.urls import path from ninja import NinjaAPI api = NinjaAPI() @api.get("/add") def add(request, a: int, b: int): return {"result": a + b} urlpatterns = [ path("admin/", admin.site.urls), path("api/", api.urls), ]
-
运行项目:
python manage.py runserver
-
访问 API:
打开浏览器,访问http://127.0.0.1:8000/api/add?a=1&b=2
,你将看到 JSON 响应为:{"result": 3}
-
交互式 API 文档:
访问http://127.0.0.1:8000/api/docs
,你将看到自动的、交互式 API 文档(由 OpenAPI / Swagger UI 或 Redoc 提供)。
NinjaAPI 的主要参数
- title:API 的标题。
- version:API 的版本。
- description:API 的描述。
- openapi_url:OpenAPI 规范的相对 URL。
- docs_url:API 文档的相对 URL。
- servers:目标主机列表,用于 OpenAPI 规范。
- csrf:是否要求 CSRF 令牌(已弃用,现在由
auth
处理)。 - auth:认证类。
- renderer:默认响应渲染器。
- parser:默认请求解析器。
- openapi_extra:OpenAPI 规范的额外属性。
示例
以下是一个更复杂的示例,展示了如何使用 NinjaAPI 创建一个带有输入和输出模型的 API:
# apidemo/api.py
from ninja import NinjaAPI, Schema
from ninja import UploadedFile, File
from django.core.files.storage import FileSystemStorage
from django.shortcuts import get_object_or_404
from .models import Employee, Department
api = NinjaAPI()
class EmployeeIn(Schema):
first_name: str
last_name: str
department_id: int = None
birthdate: date = None
class EmployeeOut(Schema):
id: int
first_name: str
last_name: str
department_id: int = None
birthdate: date = None
@api.post("/employees")
def create_employee(request, payload: EmployeeIn, cv: UploadedFile = File(...)):
fs = FileSystemStorage()
filename = fs.save(cv.name, cv)
payload_dict = payload.dict()
payload_dict['cv'] = filename
employee = Employee.objects.create(**payload_dict)
return {"id": employee.id}
@api.get("/employees/{employee_id}")
def get_employee(request, employee_id: int):
employee = get_object_or_404(Employee, id=employee_id)
return EmployeeOut.from_orm(employee)
在这个示例中,我们定义了两个模型 EmployeeIn
和 EmployeeOut
,分别用于输入和输出。我们还创建了两个 API 端点:一个用于创建员工,另一个用于获取员工信息。
在 urls.py
中使用 api.py
:
# apidemo/urls.py
from django.contrib import admin
from django.urls import path
from .api import api
urlpatterns = [
path("admin/", admin.site.urls),
path("api/", api.urls),
]
跨域请求问题
从你提供的信息来看,你遇到了一个常见的跨源资源共享(CORS)问题。这个错误信息表明,当你从 http://localhost:5173
发起请求到 http://127.0.0.1:8000/api/test/
时,服务器没有返回 Access-Control-Allow-Origin
头,导致浏览器阻止了这次请求。
解决 CORS 问题的方法
https://www.bilibili.com/video/BV1C341147VJ/
1. 在服务器端设置 CORS 头
最根本的解决方法是在服务器端设置 Access-Control-Allow-Origin
头。
手动设置
from django.http import HttpResponse
def my_view(request):
# 创建一个HttpResponse对象
response = HttpResponse("这是我的响应内容")
# 手动设置CORS头部
response['Access-Control-Allow-Origin'] = '*'
return response
如果你使用的是 Django,可以安装 django-cors-headers
库来处理 CORS 问题。
-
安装
django-cors-headers
:pip install django-cors-headers
-
在
settings.py
中配置:
# apidemo/settings.py
INSTALLED_APPS = [
...
'corsheaders',
...
]
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = ('*')
CORS_ALLOWED_ORIGINS = [
"http://localhost:5173",
]
- 确保
CORS_ALLOWED_ORIGINS
包含你的前端开发服务器的 URL。
2. 使用代理
如果你无法修改服务器端的设置,可以在开发环境中使用代理来绕过 CORS 限制。Vite 提供了代理配置选项,可以在 vite.config.js
中设置。
-
创建或修改
vite.config.js
:// vite.config.js import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], server: { proxy: { '/api': { target: 'http://127.0.0.1:8000', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } } });
-
修改请求 URL:
在前端代码中,将请求 URL 从http://127.0.0.1:8000/api/test/
改为/api/test/
。// src/components/Person.vue fetch('/api/test/') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log(data); }) .catch(error => { console.error('There was a problem with the fetch operation:', error); });
检查和重试
-
检查 URL 的合法性:
- 确保
http://127.0.0.1:8000/api/test/
是正确的,并且服务器已经启动。 - 尝试在浏览器中直接访问该 URL,看是否能返回预期的结果。
- 确保
-
重试请求:
- 有时候网络问题可能导致请求失败,可以尝试重新发送请求。
-
检查网络连接:
- 确保你的开发环境的网络连接正常,没有防火墙或代理服务器阻止请求。
总结
CORS 问题通常是由于服务器端没有正确设置 Access-Control-Allow-Origin
头导致的。你可以通过在服务器端设置 CORS 头或在开发环境中使用代理来解决这个问题。如果问题仍然存在,建议检查 URL 的合法性和网络连接,适当重试请求。
Vue开发环境ip配置
如果你是使用 Vite 创建的 Vue 3 项目,配置 IP 访问的方法略有不同。以下是如何配置 Vite 项目以便通过 IP 地址访问的步骤:
1. 修改 Vite 配置文件
Vite 的配置文件通常是 vite.config.js
或 vite.config.ts
(如果你使用 TypeScript)。你需要在这个文件中配置 server
选项,以便允许通过 IP 地址访问。
1.1 创建或修改 vite.config.js
在项目根目录下找到 vite.config.js/ vite.config.ts
文件。如果这个文件不存在,可以新建一个。
// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
server: {
host: '0.0.0.0', // 允许通过 IP 访问
port: 3000, // 设置端口
},
});
2. 检查防火墙设置
确保你的防火墙允许指定端口的流量。以下是一些常见操作系统的防火墙配置方法:
2.1 Windows
- 打开“控制面板”,选择“系统和安全”,然后选择“Windows Defender 防火墙”。
- 点击“高级设置”。
- 在“入站规则”中,创建一个新的规则,允许你的开发服务器端口(如3000)。
2.2 macOS
- 打开“系统偏好设置”,选择“安全性与隐私”。
- 选择“防火墙”标签,点击防火墙选项。
- 添加你的开发工具(如VSCode或其他IDE)到允许列表。
2.3 Linux
使用 iptables
或 ufw
等工具配置防火墙规则。例如,对于 ufw
,可以执行以下命令:
sudo ufw allow 3000
3. 使用局域网 IP 访问
完成上述配置后,你可以通过局域网的 IP 地址来访问你的 Vite 项目。
- 获取你的局域网 IP 地址。你可以通过以下命令获取:
- Windows: 打开命令提示符,输入
ipconfig
,查找你的IPv4地址。 - macOS和Linux: 打开终端,输入
ifconfig
或ip a
,查找你的IPv4地址。
- Windows: 打开命令提示符,输入
- 在另一台设备上打开浏览器,输入
http://你的IP地址:3000
(例如http://192.168.1.100:3000
),即可访问你的 Vite 项目。
Django配置nginx
Django默认不支持
https
请求,需要配置反向代理服务器
在使用Django时,通常我们会使用Nginx作为反向代理服务器来处理HTTPS请求。下面是一个基本的配置步骤:
- 安装Nginx和SSL证书:
- 在你的服务器上安装Nginx。
- 获取SSL证书和密钥文件。你可以通过Let’s Encrypt免费获取SSL证书。
- 配置Nginx:
- 打开或创建一个新的Nginx配置文件,通常位于
/etc/nginx/sites-available/
目录下。 - 在配置文件中添加或修改以下内容:
- 打开或创建一个新的Nginx配置文件,通常位于
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /path/to/your/certificate.pem;
ssl_certificate_key /path/to/your/privatekey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://127.0.0.1:8000; # 这里假设Django运行在8000端口
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
listen 80;
和return 301 https://$server_name$request_uri;
这两行配置会将所有HTTP请求重定向到HTTPS。ssl_certificate
和ssl_certificate_key
需要指向你的SSL证书和私钥文件。location /
块中的proxy_pass
指令将所有请求转发到Django服务器。你需要根据实际情况修改这个地址。
-
启用配置并重启Nginx:
-
创建一个符号链接到
/etc/nginx/sites-enabled/
目录以启用配置:sudo ln -s /etc/nginx/sites-available/your_config_file /etc/nginx/sites-enabled/
-
检查Nginx配置文件是否有语法错误:
sudo nginx -t
-
如果配置正确,重启Nginx以应用更改:
sudo systemctl restart nginx
-
-
配置Django:
-
确保Django项目能够识别HTTPS请求。你可能需要在Django的
settings.py
中设置SECURE_PROXY_SSL_HEADER
来确保Django能够信任Nginx的HTTPS转发:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
-
完成以上步骤后,你的Django应用就可以通过Nginx来处理HTTPS请求了。请根据你的实际需求调整配置。
Vue+Django部署
npm run build
将框架代码转化成静态文件
(处理好逻辑)在使用
npm run build
命令时,具体发生的事情取决于你的项目配置,特别是package.json
文件中的scripts
部分。通常情况下,这个命令用于构建前端项目,生成优化后的静态文件,以便于部署到生产环境中。以下是npm run build
常见的行为:
- 读取配置:
npm
会读取package.json
文件中的scripts
部分,查找build
命令的定义。例如,
package.json
中可能有如下定义:"scripts": { "build": "webpack --config webpack.prod.js" }
- 执行构建工具:
- 根据
package.json
中的定义,npm run build
会执行相应的构建工具。常见的构建工具包括 Webpack、Parcel、Rollup 等。- 例如,如果使用 Webpack,会根据
webpack.prod.js
配置文件进行构建。
- 代码优化:
- 压缩:构建工具通常会压缩 JavaScript 和 CSS 文件以减少文件大小,加快加载速度。
- 混淆:为了防止代码被轻易阅读和理解,构建工具可能会对 JavaScript 代码进行混淆。
- 代码拆分:根据需要将代码拆分成多个文件,以便按需加载。
- 处理资源:构建工具会处理项目中的各种资源文件,如图片、字体等,可能还会进行优化(例如压缩图片)。
- 生成静态文件:
- 构建完成后,会生成优化后的静态文件,通常放在一个特定的目录中,比如
dist
或build
。- 这些静态文件可以直接用于部署到 Web 服务器,如 Nginx、Apache 等。
- 环境变量:
- 构建过程可能会使用不同的环境变量,例如生产环境下的 API 地址、密钥等。这些变量通常在构建时加载,确保生成的文件适用于生产环境。
- 错误处理:
- 如果构建过程中出现错误,
npm run build
会显示错误信息,帮助开发者定位和解决问题。请注意,不同的项目可能会有不同的构建配置和工具,具体的行为需要根据项目的
package.json
文件来确定。如果你有具体的项目配置文件,可以查看其中的build
脚本来了解详细的构建步骤。
Vue模板路径转换
Vue项目打包后,资源的路径会发生变化,开发环境和生产环境必然不同。
无论是Vite还是Webpack,假设图片路径是写在
模板标签的属性
中的,构建工具都会帮我们处理路径转换的问题,但是题目中的资源路径被保存在一个const变量
中,自然就找不到对应的图片