python:Django 和 Vue.js 技术栈解析
安装 Django
pip install django
Downloading django-4.2.24-py3-none-any.whl (8.0 MB)
pip install djangorestframework django-cors-headers
Downloading djangorestframework-3.16.1-py3-none-any.whl (1.1 MB)
Downloading django_cors_headers-4.9.0-py3-none-any.whl (12 kB)
where django-admin
D:\Python39\Scripts\django-admin.exe
D:\Python39\Scripts> django-admin
Type ‘django-admin help ’ for help on a specific subcommand.
django-admin startproject myproject
django-admin startapp myapp
Django 和 Vue.js 是当前主流的 Web 开发技术组合,分别承担 后端服务 和 前端交互 的核心角色。二者通过合理协作,可快速构建高性能、易维护的现代化 Web 应用(如管理系统、电商平台、社交应用等)。以下从技术定位、协作原理、实战流程、优劣势及常见问题等方面,全面解析这一技术栈。
一、核心定位:Django 与 Vue.js 的分工
首先需明确二者的本质差异——Django 是“后端框架”,Vue.js 是“前端框架”,职责边界清晰,不存在直接竞争关系,而是互补协作。
维度 | Django(后端) | Vue.js(前端) |
---|---|---|
核心职责 | 处理业务逻辑、数据存储、权限控制、API 接口提供、安全验证(如 CSRF、XSS 防护)等 | 处理页面渲染、用户交互(如表单提交、动态数据展示)、前端路由、状态管理等 |
技术本质 | 基于 Python 的“全栈式后端框架”(内置 ORM、Admin 后台、模板引擎等) | 基于 JavaScript 的“渐进式前端框架”(核心聚焦视图层,可按需集成路由、状态管理) |
运行环境 | 服务器端(如 Linux 服务器,依赖 Python 解释器) | 客户端(用户浏览器,或通过 Node.js 进行服务端渲染/构建) |
数据处理方式 | 操作数据库(通过 ORM 或原生 SQL),返回结构化数据(如 JSON) | 接收后端 JSON 数据,通过组件化渲染到页面,响应用户操作并反馈给后端 |
二、协作原理:前后端如何通信?
Django 与 Vue.js 的协作核心是 “后端提供 API,前端调用 API”,即“前后端分离”模式(也可兼容 Django 模板混合模式,但分离模式更主流)。
1. 核心通信流程
-
后端(Django):编写 API 接口
Django 通过Django REST Framework
(DRF,Django 生态中最成熟的 API 工具)或原生JsonResponse
,将数据库数据封装为 JSON 格式 的 API 接口(如GET /api/users/
获取用户列表,POST /api/login/
处理登录请求)。
示例(Django + DRF 编写用户列表 API):# views.py from rest_framework import viewsets from .models import User from .serializers import UserSerializerclass UserViewSet(viewsets.ReadOnlyModelViewSet):queryset = User.objects.all() # 从数据库获取用户数据serializer_class = UserSerializer # 将数据序列化为 JSON
-
前端(Vue.js):调用 API 获取数据
Vue 通过axios
(HTTP 客户端库)发送请求到 Django 的 API 地址,接收 JSON 数据后,渲染到页面组件中。
示例(Vue 组件调用用户列表 API):<template><div><h2>用户列表</h2><ul><li v-for="user in userList" :key="user.id">{{ user.username }}</li></ul></div> </template><script> import axios from 'axios' // 引入 HTTP 工具export default {data() {return {userList: [] // 存储后端返回的用户数据}},mounted() {// 页面加载时调用 Django APIaxios.get('http://localhost:8000/api/users/').then(response => {this.userList = response.data // 将 JSON 数据赋值给 userList}).catch(error => {console.error('获取用户数据失败:', error)})} } </script>
-
跨域问题解决
由于前端(如http://localhost:8080
)和后端(如http://localhost:8000
)端口不同,浏览器会触发 跨域资源共享(CORS) 限制,导致请求失败。
解决方案:在 Django 中安装django-cors-headers
插件,允许前端域名的请求:# settings.py INSTALLED_APPS = [# ... 其他应用'corsheaders', # 注册 CORS 应用 ]MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware', # 放在中间件最前面# ... 其他中间件 ]# 允许所有前端域名(开发环境用,生产环境需指定具体域名,如 CORS_ALLOWED_ORIGINS = ['https://yourdomain.com']) CORS_ALLOW_ALL_ORIGINS = True # 开发环境专用,生产环境禁用
三、实战流程:从 0 搭建 Django + Vue.js 项目
以“简单用户管理系统”为例,完整流程分为 后端搭建(Django) 和 前端搭建(Vue.js) 两部分。
阶段 1:搭建 Django 后端(提供 API)
1. 环境准备
- 安装 Python(3.8+)和
pip
(Python 包管理工具)。 - 安装 Django 和必要依赖:
# 创建虚拟环境(可选但推荐,避免依赖冲突) python -m venv venv # 激活虚拟环境(Windows):venv\Scripts\activate;(Linux/Mac):source venv/bin/activate # 安装 Django、DRF、CORS 插件 pip install django djangorestframework django-cors-headers
2. 创建 Django 项目与应用
# 创建 Django 项目(项目名:backend)
django-admin startproject backend
cd backend
# 创建应用(应用名:users,负责用户相关功能)
python manage.py startapp users
3. 配置 Django(数据库、API、CORS)
- 配置数据库:默认使用 SQLite(无需额外安装),直接在
settings.py
中注册应用:INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',# 第三方应用'rest_framework','corsheaders',# 自定义应用'users', ]
- 定义数据模型(Model):在
users/models.py
中定义用户模型(此处复用 Django 内置 User 模型):from django.contrib.auth.models import User # 复用内置用户模型
- 创建序列化器(Serializer):在
users/serializers.py
中定义数据序列化规则(将 Model 转为 JSON):from rest_framework import serializers from django.contrib.auth.models import Userclass UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ['id', 'username', 'email'] # 需返回的字段
- 配置 URL 路由:
- 在
backend/urls.py
中指定应用路由:from django.contrib import admin from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('api/', include('users.urls')), # 所有 /api/ 开头的请求指向 users 应用 ]
- 在
users/
下创建urls.py
,定义具体 API 路由:from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import UserViewSetrouter = DefaultRouter() router.register(r'users', UserViewSet) # 注册 /api/users/ 接口urlpatterns = [path('', include(router.urls)), ]
- 在
- 配置 CORS:参考前文“跨域问题解决”,在
settings.py
中添加 CORS 中间件和允许的域名。
4. 启动 Django 服务
# 生成数据库迁移文件(同步 Model 到数据库)
python manage.py makemigrations
python manage.py migrate
# 创建超级用户(用于登录 Django Admin 后台)
python manage.py createsuperuser
# 启动服务(默认端口 8000)
python manage.py runserver
此时,访问 http://localhost:8000/api/users/
可看到 JSON 格式的用户列表(初始只有超级用户),API 搭建完成。
阶段 2:搭建 Vue.js 前端(调用 API)
1. 环境准备
- 安装 Node.js(14+,自带
npm
包管理工具)。 - 安装 Vue CLI(Vue 项目脚手架):
npm install -g @vue/cli
2. 创建 Vue 项目
# 创建 Vue 项目(项目名:frontend)
vue create frontend
# 选择默认配置(Default ([Vue 3] babel, eslint))或手动配置(如需路由、状态管理)
cd frontend
# 安装 axios(用于发送 HTTP 请求)
npm install axios
3. 编写 Vue 组件(调用 Django API)
修改 src/components/HelloWorld.vue
(或新建组件),实现“获取用户列表”功能:
<template><div class="hello"><h1>用户管理系统</h1><div v-if="loading">加载中...</div><div v-else-if="error" style="color: red;">{{ error }}</div><table v-else border="1" cellpadding="8" cellspacing="0"><tr><th>ID</th><th>用户名</th><th>邮箱</th></tr><tr v-for="user in userList" :key="user.id"><td>{{ user.id }}</td><td>{{ user.username }}</td><td>{{ user.email }}</td></tr></table></div>
</template><script>
import axios from 'axios'export default {name: 'HelloWorld',data() {return {userList: [],loading: false,error: ''}},methods: {async fetchUsers() { // 使用 async/await 简化异步请求this.loading = truetry {const response = await axios.get('http://localhost:8000/api/users/')this.userList = response.datathis.error = ''} catch (err) {this.error = '获取用户数据失败,请检查后端服务是否启动'console.error(err)} finally {this.loading = false}}},mounted() {this.fetchUsers() // 页面加载时执行请求}
}
</script><style scoped>
table { margin-top: 20px; }
th { background-color: #f5f5f5; }
</style>
4. 启动 Vue 服务
npm run serve
访问 http://localhost:8080
,即可看到从 Django 后端获取的用户列表,前后端协作成功。
四、进阶功能:完善技术栈
当项目复杂度提升时,需补充以下工具/功能,确保扩展性和可维护性:
1. 前端进阶
- 路由管理:使用
vue-router
实现多页面跳转(如“用户列表”“用户详情”“登录页”)。npm install vue-router@4 # Vue 3 对应 vue-router 4
- 状态管理:使用
pinia
(Vue 官方推荐,替代 Vuex)管理全局状态(如用户登录信息、购物车数据)。npm install pinia
- UI 组件库:使用
Element Plus
(Vue 3)或Vuetify
快速构建美观的界面,减少重复开发。npm install element-plus
2. 后端进阶
- 权限控制:通过 DRF 的
TokenAuthentication
或JWT
(djangorestframework-simplejwt
)实现用户登录认证,防止未授权访问 API。pip install djangorestframework-simplejwt
- 过滤与分页:使用 DRF 的
FilterSet
(django-filter
)和PageNumberPagination
实现数据筛选(如按用户名搜索)和分页(避免一次性返回大量数据)。pip install django-filter
- 数据库优化:当数据量较大时,将默认的 SQLite 替换为 PostgreSQL 或 MySQL,提升性能;同时使用 Django ORM 的
select_related
/prefetch_related
减少数据库查询次数。
五、优劣势分析:适合哪些场景?
优势
- 开发效率高:Django 内置 Admin 后台(无需手写管理界面)、ORM(无需写原生 SQL);Vue 组件化开发(可复用代码)、指令系统(简化 DOM 操作)。
- 生态成熟:二者均有丰富的第三方库(DRF、Element Plus、pinia 等),问题解决方案多,社区活跃。
- 用户体验好:Vue 实现前端异步刷新(无页面跳转),配合 AJAX 请求,用户操作流畅;Django 处理后端逻辑稳定,接口响应快。
- 易维护性:前后端分离架构,职责清晰,便于团队分工(后端专注 API,前端专注交互),后期迭代时修改互不影响。
劣势
- 学习成本:需同时掌握 Python(Django)和 JavaScript(Vue)两门语言,以及相关工具(DRF、axios 等),新手入门周期较长。
- 部署复杂度:相比传统的“Django 模板渲染”,前后端分离需分别部署后端服务(如 Nginx + Gunicorn 部署 Django)和前端静态资源(如 Nginx 部署 Vue 打包后的文件),步骤更繁琐。
适合场景
- 中大型 Web 应用(如管理系统、电商平台、SaaS 服务)。
- 对用户交互体验要求高(如动态加载、无刷新提交)的项目。
- 团队有明确前后端分工,需长期维护迭代的项目。
六、常见问题与解决方案
-
API 调用返回 403 Forbidden
- 原因:Django 的 CSRF 防护机制拦截了非浏览器表单请求(前后端分离模式下,前端请求未携带 CSRF Token)。
- 解决方案:若使用 Token/JWT 认证,可在
settings.py
中注释掉django.middleware.csrf.CsrfViewMiddleware
中间件(仅在前后端分离且用其他认证方式时推荐)。
-
Vue 无法获取 Django 数据,控制台报 CORS 错误
- 原因:Django 未配置 CORS,不允许前端域名的请求。
- 解决方案:确保已安装
django-cors-headers
,并在settings.py
中添加 CORS 中间件和允许的前端域名(生产环境禁用CORS_ALLOW_ALL_ORIGINS = True
,需指定具体域名如CORS_ALLOWED_ORIGINS = ['https://your-frontend.com']
)。
-
Django API 返回数据格式不符合预期
- 原因:序列化器配置错误(如字段遗漏、字段类型不匹配)。
- 解决方案:检查
serializers.py
中的fields
是否包含所需字段,或通过fields = '__all__'
临时返回所有字段,排查问题。
七、总结
Django + Vue.js 是一套“后端稳定、前端灵活”的 Web 开发组合,通过“后端提供 API + 前端调用 API”的模式,实现了前后端解耦,既发挥了 Django 在业务逻辑、数据安全上的优势,也利用了 Vue 在用户交互、页面渲染上的特长。
对于新手,建议先分别掌握 Django(如编写 API、使用 ORM)和 Vue(如组件化、axios 请求)的基础,再通过小型项目(如待办清单、博客系统)实践二者协作,逐步过渡到复杂项目。
如何添加 REST 风格?
在 Django 中实现 REST 风格的 API,核心是遵循 REST(Representational State Transfer,表述性状态转移)的设计原则,即通过统一的 HTTP 方法(GET、POST、PUT、DELETE 等)操作资源,使用 URL 表示资源,返回结构化数据(如 JSON),且无状态通信。
结合 Django REST Framework(DRF)可以快速实现 REST 风格的 API,以下是具体步骤和最佳实践:
一、REST 风格的核心原则(设计基础)
在设计 API 前,需明确 REST 的核心规范:
- 资源标识:用 URL 表示资源(如
/api/users/
表示用户列表,/api/users/1/
表示 ID 为 1 的用户)。 - HTTP 方法语义:
GET
:获取资源(查询)POST
:创建资源PUT/PATCH
:更新资源(PUT 全量更新,PATCH 部分更新)DELETE
:删除资源
- 无状态:每个请求必须包含所有必要信息,服务器不存储客户端状态。
- 响应格式:返回 JSON 或 XML 等结构化数据(推荐 JSON)。
- 状态码:使用标准 HTTP 状态码(如 200 成功、201 创建成功、400 错误请求、404 资源不存在)。
二、使用 Django REST Framework 实现 REST 风格 API
DRF 是 Django 生态中最成熟的 REST API 工具,内置了符合 REST 原则的视图、序列化器、路由等组件,无需从零开发。
1. 环境准备(已安装可跳过)
# 安装 DRF(需先安装 Django)
pip install djangorestframework
在 settings.py
中注册 DRF:
INSTALLED_APPS = [# ... 其他应用'rest_framework', # 注册 DRF
]
2. 定义资源模型(Model)
以“文章(Article)”资源为例,先定义数据模型(对应数据库表):
# app/models.py
from django.db import modelsclass Article(models.Model):title = models.CharField(max_length=100, verbose_name="标题")content = models.TextField(verbose_name="内容")created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")class Meta:verbose_name = "文章"verbose_name_plural = "文章"def __str__(self):return self.title
3. 创建序列化器(Serializer)
序列化器用于将模型实例(资源)转换为 JSON(序列化),或接收 JSON 转换为模型实例(反序列化),是 REST 风格中“表述性状态”的核心。
在 app
目录下创建 serializers.py
:
# app/serializers.py
from rest_framework import serializers
from .models import Articleclass ArticleSerializer(serializers.ModelSerializer):class Meta:model = Articlefields = ['id', 'title', 'content', 'created_at', 'updated_at'] # 需序列化的字段read_only_fields = ['id', 'created_at', 'updated_at'] # 这些字段只能由服务器生成(如 ID、创建时间)
4. 编写 REST 风格的视图(View)
DRF 提供了 ViewSet
类,封装了符合 REST 原则的默认方法(list
、retrieve
、create
、update
、destroy
),对应 HTTP 方法和资源操作:
ViewSet 方法 | 对应 HTTP 方法 | 功能描述 | 示例 URL |
---|---|---|---|
list | GET | 获取资源列表 | /api/articles/ |
retrieve | GET | 获取单个资源(按 ID) | /api/articles/1/ |
create | POST | 创建新资源 | /api/articles/ |
update | PUT | 全量更新资源(按 ID) | /api/articles/1/ |
partial_update | PATCH | 部分更新资源(按 ID) | /api/articles/1/ |
destroy | DELETE | 删除资源(按 ID) | /api/articles/1/ |
实现视图:
# app/views.py
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializerclass ArticleViewSet(viewsets.ModelViewSet):"""符合 REST 风格的文章资源视图集自动提供 list/retrieve/create/update/partial_update/destroy 方法"""queryset = Article.objects.all() # 资源列表的查询集serializer_class = ArticleSerializer # 关联的序列化器
5. 配置 REST 风格的 URL 路由
DRF 的 DefaultRouter
会自动根据 ViewSet
生成符合 REST 规范的 URL 路由(无需手动定义每个 HTTP 方法的 URL)。
在 app
目录下创建 urls.py
:
# app/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ArticleViewSet# 创建路由器并注册视图集
router = DefaultRouter()
router.register(r'articles', ArticleViewSet) # 资源路径为 /api/articles/# 生成 URL 配置
urlpatterns = [path('', include(router.urls)),
]
在项目主 urls.py
中引入:
# project/urls.py
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('api/', include('app.urls')), # 所有 REST API 前缀为 /api/
]
6. 测试 REST API(验证风格)
启动 Django 服务:
python manage.py makemigrations # 生成迁移文件
python manage.py migrate # 同步数据库
python manage.py runserver # 启动服务(默认 http://localhost:8000)
通过工具(如 Postman、浏览器、curl)测试 API,验证是否符合 REST 风格:
-
获取文章列表(GET)
请求:GET http://localhost:8000/api/articles/
响应(JSON):[{"id": 1,"title": "第一篇文章","content": "REST 风格 API 示例","created_at": "2025-09-28T10:00:00Z","updated_at": "2025-09-28T10:00:00Z"} ]
-
创建文章(POST)
请求:POST http://localhost:8000/api/articles/
请求体(JSON):{"title": "第二篇文章","content": "DRF 实现 REST" }
响应(状态码 201 Created):
{"id": 2,"title": "第二篇文章","content": "DRF 实现 REST","created_at": "2025-09-28T10:30:00Z","updated_at": "2025-09-28T10:30:00Z" }
-
更新文章(PUT)
请求:PUT http://localhost:8000/api/articles/2/
请求体(全量更新):{"title": "第二篇文章(更新)","content": "DRF 实现 REST 风格" }
响应(状态码 200 OK):返回更新后的资源。
-
删除文章(DELETE)
请求:DELETE http://localhost:8000/api/articles/2/
响应(状态码 204 No Content):无返回体,资源已删除。
三、进阶:完善 REST 风格的细节
1. 分页(避免大量数据一次性返回)
在 settings.py
中配置全局分页:
REST_FRAMEWORK = {'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination','PAGE_SIZE': 10 # 每页 10 条数据
}
此时 GET /api/articles/
会返回分页信息:
{"count": 20, # 总条数"next": "http://localhost:8000/api/articles/?page=2", # 下一页 URL"previous": null, # 上一页 URL(第一页为 null)"results": [...] # 当前页数据
}
2. 过滤与排序(按条件查询资源)
安装 django-filter
实现过滤:
pip install django-filter
在 settings.py
中配置:
REST_FRAMEWORK = {# ... 其他配置'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}
在视图中指定可过滤字段:
# app/views.py
from django_filters.rest_framework import DjangoFilterBackendclass ArticleViewSet(viewsets.ModelViewSet):queryset = Article.objects.all()serializer_class = ArticleSerializerfilter_backends = [DjangoFilterBackend]filterset_fields = ['title'] # 允许按 title 过滤
现在可通过 GET /api/articles/?title=第一篇
过滤标题包含“第一篇”的文章。
3. 认证与权限(保护资源)
添加 JWT 认证(无状态,符合 REST 原则):
pip install djangorestframework-simplejwt
在 settings.py
中配置:
REST_FRAMEWORK = {# ... 其他配置'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',),
}
在视图中限制权限(如仅登录用户可创建文章):
# app/views.py
from rest_framework.permissions import IsAuthenticated, IsAdminUserclass ArticleViewSet(viewsets.ModelViewSet):queryset = Article.objects.all()serializer_class = ArticleSerializer# 权限配置:列表和详情允许匿名访问,创建/更新/删除需登录def get_permissions(self):if self.action in ['create', 'update', 'partial_update', 'destroy']:return [IsAuthenticated()]return []
4. 自定义响应格式(统一结构)
为所有响应添加统一格式(如 {"code": 200, "message": "success", "data": ...}
),需自定义渲染器:
# app/renderers.py
from rest_framework.renderers import JSONRendererclass CustomJSONRenderer(JSONRenderer):def render(self, data, accepted_media_type=None, renderer_context=None):# 处理错误响应(如 400、404)if isinstance(data, dict) and 'detail' in data:response = {'code': renderer_context['response'].status_code,'message': data['detail'],'data': None}else:response = {'code': renderer_context['response'].status_code,'message': 'success','data': data}return super().render(response, accepted_media_type, renderer_context)
在 settings.py
中应用:
REST_FRAMEWORK = {# ... 其他配置'DEFAULT_RENDERER_CLASSES': ['app.renderers.CustomJSONRenderer']
}
四、总结
通过 Django REST Framework 实现 REST 风格 API 的核心步骤:
- 定义资源模型(Model);
- 创建序列化器(Serializer),处理资源与 JSON 的转换;
- 使用
ViewSet
提供符合 HTTP 方法语义的操作(list/retrieve/create 等); - 通过
DefaultRouter
自动生成 REST 风格的 URL; - 补充分页、过滤、认证等功能,完善 API 规范。
这种设计确保了 API 的一致性、可扩展性和无状态性,符合 REST 架构的核心思想,便于前端(如 Vue.js)调用和维护。