Django 和 Vue3 前后端分离开发笔记

Django 和 Vue3 前后端分离开发笔记

1. Django Ninja API

Django Ninja 是一个用于使用 Django 和 Python 3.6+ 类型提示构建 API 的网络框架。它具有以下主要特点:

  1. 简单易懂:设计为易于使用和符合直觉,适合快速上手。
  2. 快速执行:多亏了 Pydantic 和异步支持,具有非常高的性能。
  3. 快速编程:类型提示和自动文档生成让开发者只需关注业务逻辑。
  4. 基于标准:基于 OpenAPI(以前称为 Swagger)和 JSON 模式。
  5. 对 Django 友好:与 Django 核心和 ORM 有良好的集成。
  6. 可用于生产:被多家公司用于实际项目,稳定可靠。
创建和使用 NinjaAPI
  1. 安装 Django Ninja

    sh 复制代码
    pip install django-ninja
  2. 创建 Django 项目(如果还没有):

    sh 复制代码
    django-admin startproject apidemo
    cd apidemo
  3. urls.py 中配置 API

    python 复制代码
    # 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),
    ]
  4. 运行项目

    sh 复制代码
    python manage.py runserver
  5. 访问 API

    打开浏览器,访问 http://127.0.0.1:8000/api/add?a=1&b=2,你将看到 JSON 响应为:

    json 复制代码
    {"result": 3}
  6. 交互式 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:

python 复制代码
# 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)

在这个示例中,我们定义了两个模型 EmployeeInEmployeeOut,分别用于输入和输出。我们还创建了两个 API 端点:一个用于创建员工,另一个用于获取员工信息。

urls.py 中使用 api.py
python 复制代码
# 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),
]

2. 跨域请求问题

从你提供的信息来看,你遇到了一个常见的跨源资源共享(CORS)问题。这个错误信息表明,当你从 http://localhost:5173 发起请求到 http://127.0.0.1:8000/api/test/ 时,服务器没有返回 Access-Control-Allow-Origin 头,导致浏览器阻止了这次请求。

解决 CORS 问题的方法
1. 在服务器端设置 CORS 头

最根本的解决方法是在服务器端设置 Access-Control-Allow-Origin 头。

手动设置

python 复制代码
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 问题。

  1. 安装 django-cors-headers

    sh 复制代码
    pip install django-cors-headers
  2. settings.py 中配置

    python 复制代码
    # apidemo/settings.py
    
    INSTALLED_APPS = [
        ...
        'corsheaders',
        ...
    ]
    
    MIDDLEWARE = [
        ...
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        ...
    ]
    
    CORS_ALLOWED_ORIGINS = [
        "http://localhost:5173",
    ]
  3. 确保 CORS_ALLOWED_ORIGINS 包含你的前端开发服务器的 URL

2. 使用代理

如果你无法修改服务器端的设置,可以在开发环境中使用代理来绕过 CORS 限制。Vite 提供了代理配置选项,可以在 vite.config.js 中设置。

  1. 创建或修改 vite.config.js

    javascript 复制代码
    // 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/, '')
          }
        }
      }
    });
  2. 修改请求 URL

    在前端代码中,将请求 URL 从 http://127.0.0.1:8000/api/test/ 改为 /api/test/

    javascript 复制代码
    // 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);
      });
检查和重试
  1. 检查 URL 的合法性

    • 确保 http://127.0.0.1:8000/api/test/ 是正确的,并且服务器已经启动。
    • 尝试在浏览器中直接访问该 URL,看是否能返回预期的结果。
  2. 重试请求

    • 有时候网络问题可能导致请求失败,可以尝试重新发送请求。
  3. 检查网络连接

    • 确保你的开发环境的网络连接正常,没有防火墙或代理服务器阻止请求。
总结

CORS 问题通常是由于服务器端没有正确设置 Access-Control-Allow-Origin 头导致的。你可以通过在服务器端设置 CORS 头或在开发环境中使用代理来解决这个问题。如果问题仍然存在,建议检查 URL 的合法性和网络连接,适当重试请求。

Vue3 前端项目设置

1. 创建 Vue3 项目

你可以使用 Vue CLI 或 Vite 来创建 Vue3 项目。这里以 Vite 为例:

sh 复制代码
npm create vite@latest frontend --template vue
cd frontend
npm install
npm install axios
2. 配置 main.js

确保在 main.js 中引入 Vue 和 Axios:

javascript 复制代码
// frontend/src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import axios from 'axios'

const app = createApp(App)
app.config.globalProperties.$axios = axios
app.mount('#app')
3. 创建组件

创建一个简单的组件来测试 API 请求:

vue 复制代码
<!-- frontend/src/components/Person.vue -->
<template>
    <div>
        <button @click="sendRequest">发送请求</button>
        <hr>
        <p>{{ response }}</p>
    </div>
</template>

<script setup>
import { ref } from 'vue';
import axios from 'axios';

const response = ref(null);

async function sendRequest() {
    try {
        const res = await axios.get('/api/test/');
        response.value = res.data;
    } catch (error) {
        console.error('请求失败:', error);
    }
}
</script>

<style scoped>
button {
    padding: 10px 20px;
    margin-bottom: 10px;
}
</style>
4. 运行 Vue3 项目
sh 复制代码
npm run dev

确保你的 Vue3 项目运行在 http://localhost:5173,并且通过 Vite 配置的代理正确地将请求发送到 Django 后端。

数据库模型示例

为了完整演示,这里提供一个简单的数据库模型示例:

python 复制代码
# apidemo/models.py
from django.db import models

class Department(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Employee(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True, blank=True)
    birthdate = models.DateField(null=True, blank=True)
    cv = models.FileField(upload_to='cvs/', null=True, blank=True)

    def __str__(self):
        return f"{self.first_name} {self.last_name}"
5. 迁移数据库
sh 复制代码
python manage.py makemigrations
python manage.py migrate

测试和调试

  1. 确保后端和前端都在运行

    • 后端:http://127.0.0.1:8000
    • 前端:http://localhost:5173
  2. 检查浏览器控制台

    • 查看是否有任何错误信息。
    • 确认请求是否成功,并且返回的数据是否正确。
  3. 使用 Postman 或浏览器开发者工具

    • 使用 Postman 测试 API 端点。
    • 使用浏览器开发者工具查看网络请求和响应。
相关推荐
vyuvyucd2 分钟前
Qwen-1.8B-Chat昇腾Atlas800TA2部署实战
python
轻竹办公PPT8 分钟前
2026 年工作计划 PPT 内容拆解,对比不同 AI 生成思路
人工智能·python·powerpoint
癫狂的兔子20 分钟前
【Python】【Flask】抽奖功能
开发语言·python·flask
linuxxx11037 分钟前
python变量引用的小案例
python
问今域中1 小时前
Spring Boot 请求参数绑定注解
java·spring boot·后端
计算机程序设计小李同学1 小时前
婚纱摄影集成管理系统小程序
java·vue.js·spring boot·后端·微信小程序·小程序
2501_936146041 小时前
烟草叶片病害检测_YOLO11-C3k2-MSBlock模型详解
python
高溪流1 小时前
3.数据库表的基本操作
数据库·mysql
Data_agent1 小时前
Python 编程实战:函数与模块化编程及内置模块探索
开发语言·python
十铭忘1 小时前
windows系统python开源项目环境配置1
人工智能·python