1. 项目概述Python 100天从新手到大师系列的第53天聚焦于前后端分离开发模式的入门与实践。这个阶段标志着学习者从传统单体架构向现代Web开发范式的关键转变。作为全栈开发的核心技能点前后端分离不仅是技术架构的升级更是开发思维和工作流程的革新。在传统Web开发中Django这类框架通常采用服务端渲染(SSR)模式前后端代码高度耦合。而现代开发实践中Vue.js等前端框架的崛起使得前后端可以完全解耦通过API进行数据交互。这种分离带来了开发效率、团队协作和系统可维护性的全面提升。2. 前后端分离的核心概念2.1 传统与分离架构对比传统MVC架构中Django同时处理业务逻辑和页面渲染# views.py (传统方式) def product_list(request): products Product.objects.all() return render(request, shop/list.html, {products: products})前后端分离后Django仅提供JSON数据# views.py (分离方式) from rest_framework.response import Response def product_list_api(request): products Product.objects.all() serializer ProductSerializer(products, manyTrue) return Response(serializer.data)2.2 技术栈选择考量后端选择Django REST framework(DRF)的三大理由与Django无缝集成复用现有模型和认证系统内置强大的序列化器和视图类减少样板代码完善的文档和社区支持降低学习曲线前端选择Vue.js的关键优势渐进式框架设计可按需引入功能响应式数据绑定简化DOM操作丰富的生态系统(Vuex, Vue Router等)3. 项目环境搭建3.1 后端环境配置使用Poetry管理Python依赖(比pip更优的选择)poetry init poetry add django djangorestframework django-cors-headers关键配置项说明# settings.py INSTALLED_APPS [ ... rest_framework, corsheaders, ] MIDDLEWARE [ corsheaders.middleware.CorsMiddleware, # 必须放在最前 ... ] CORS_ALLOWED_ORIGINS [ http://localhost:8080, # Vue开发服务器地址 ]3.2 前端环境准备推荐使用Vite创建Vue项目(比Vue CLI更快)npm create vitelatest frontend --template vue cd frontend npm install axios vue-router pinia项目结构建议frontend/ ├─ public/ ├─ src/ │ ├─ api/ # API请求封装 │ ├─ assets/ │ ├─ components/ │ ├─ router/ # 路由配置 │ ├─ stores/ # Pinia状态管理 │ └─ views/ # 页面组件 └─ vite.config.js4. 核心功能实现4.1 RESTful API设计DRF中的视图集(ViewSets)最佳实践# views.py from rest_framework import viewsets class ProductViewSet(viewsets.ModelViewSet): queryset Product.objects.all() serializer_class ProductSerializer def get_queryset(self): queryset super().get_queryset() category self.request.query_params.get(category) if category: queryset queryset.filter(categorycategory) return queryset路由配置优化# urls.py from rest_framework.routers import DefaultRouter router DefaultRouter() router.register(rproducts, ProductViewSet) urlpatterns [ path(api/, include(router.urls)), ]4.2 前端数据交互封装axios实例实现统一错误处理// api/request.js import axios from axios const service axios.create({ baseURL: http://localhost:8000/api, timeout: 5000 }) service.interceptors.response.use( response response.data, error { console.error(API Error:, error.response) return Promise.reject(error) } ) export default service组合式API调用示例// api/product.js import request from ./request export const getProducts (params) request.get(/products, { params }) export const createProduct (data) request.post(/products, data)5. 开发调试技巧5.1 接口调试工具链推荐使用PostmanSwagger的双工具方案安装drf-yasg生成Swagger文档poetry add drf-yasg配置自动API文档# urls.py from drf_yasg.views import get_schema_view from drf_yasg import openapi schema_view get_schema_view( openapi.Info(titleAPI Docs, default_versionv1), publicTrue, ) urlpatterns [ ... path(swagger/, schema_view.with_ui(swagger)), ]5.2 跨域问题深度解决除基本CORS配置外还需注意开发环境下配置代理避免跨域// vite.config.js server: { proxy: { /api: { target: http://localhost:8000, changeOrigin: true, rewrite: path path.replace(/^\/api/, ) } } }生产环境Nginx配置示例location /api { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }6. 项目部署策略6.1 后端部署要点使用GunicornNginx的生产级部署# 安装Gunicorn poetry add gunicorn # 启动命令 gunicorn --bind 0.0.0.0:8000 --workers 4 project.wsgi:application关键Nginx配置location /static/ { alias /path/to/staticfiles/; expires 30d; } location /media/ { alias /path/to/media/; expires 30d; } location /api { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; }6.2 前端部署优化Vite生产构建命令npm run build部署优化建议开启Brotli压缩// vite.config.js import viteCompression from vite-plugin-compression plugins: [ viteCompression({ algorithm: brotliCompress }) ]配置CDN加速静态资源build: { rollupOptions: { output: { chunkFileNames: assets/[hash].js, assetFileNames: assets/[hash][extname] } } }7. 常见问题解决方案7.1 认证与权限控制JWT认证实现方案# settings.py REST_FRAMEWORK { DEFAULT_AUTHENTICATION_CLASSES: ( rest_framework_simplejwt.authentication.JWTTokenUserAuthentication, ) } # urls.py from rest_framework_simplejwt.views import TokenObtainPairView urlpatterns [ path(api/token/, TokenObtainPairView.as_view()), ]前端Token处理// 请求拦截器 service.interceptors.request.use(config { const token localStorage.getItem(access_token) if (token) { config.headers.Authorization Bearer ${token} } return config })7.2 性能优化实践数据库查询优化技巧# 使用select_related减少查询次数 queryset Product.objects.select_related(category).all() # 使用prefetch_related优化多对多关系 queryset Order.objects.prefetch_related(items__product)前端懒加载实现// 路由懒加载 const ProductList () import(../views/ProductList.vue) // 图片懒加载 img v-lazyproduct.image altproduct8. 项目进阶方向8.1 微服务架构演进从单体到微服务的过渡策略先按功能模块拆分API服务引入API Gateway统一入口逐步将共享模型拆分为独立服务8.2 实时功能扩展WebSocket集成方案# 安装Channels poetry add channels # routing.py from channels.routing import ProtocolTypeRouter from django.core.asgi import get_asgi_application application ProtocolTypeRouter({ http: get_asgi_application(), websocket: AuthMiddlewareStack( URLRouter([ path(ws/notifications/, NotificationConsumer.as_asgi()), ]) ), })前端连接示例const socket new WebSocket(ws://localhost:8000/ws/notifications/) socket.onmessage (e) { const data JSON.parse(e.data) // 处理实时通知 }前后端分离开发模式的学习曲线可能会让初学者感到有些陡峭特别是在处理跨域、状态管理和API设计等方面。建议从简单的CRUD功能开始实践逐步添加认证、分页、过滤等复杂功能。在实际项目中保持API文档与代码同步更新是团队协作的关键。
Python前后端分离开发:Django与Vue.js实战指南
1. 项目概述Python 100天从新手到大师系列的第53天聚焦于前后端分离开发模式的入门与实践。这个阶段标志着学习者从传统单体架构向现代Web开发范式的关键转变。作为全栈开发的核心技能点前后端分离不仅是技术架构的升级更是开发思维和工作流程的革新。在传统Web开发中Django这类框架通常采用服务端渲染(SSR)模式前后端代码高度耦合。而现代开发实践中Vue.js等前端框架的崛起使得前后端可以完全解耦通过API进行数据交互。这种分离带来了开发效率、团队协作和系统可维护性的全面提升。2. 前后端分离的核心概念2.1 传统与分离架构对比传统MVC架构中Django同时处理业务逻辑和页面渲染# views.py (传统方式) def product_list(request): products Product.objects.all() return render(request, shop/list.html, {products: products})前后端分离后Django仅提供JSON数据# views.py (分离方式) from rest_framework.response import Response def product_list_api(request): products Product.objects.all() serializer ProductSerializer(products, manyTrue) return Response(serializer.data)2.2 技术栈选择考量后端选择Django REST framework(DRF)的三大理由与Django无缝集成复用现有模型和认证系统内置强大的序列化器和视图类减少样板代码完善的文档和社区支持降低学习曲线前端选择Vue.js的关键优势渐进式框架设计可按需引入功能响应式数据绑定简化DOM操作丰富的生态系统(Vuex, Vue Router等)3. 项目环境搭建3.1 后端环境配置使用Poetry管理Python依赖(比pip更优的选择)poetry init poetry add django djangorestframework django-cors-headers关键配置项说明# settings.py INSTALLED_APPS [ ... rest_framework, corsheaders, ] MIDDLEWARE [ corsheaders.middleware.CorsMiddleware, # 必须放在最前 ... ] CORS_ALLOWED_ORIGINS [ http://localhost:8080, # Vue开发服务器地址 ]3.2 前端环境准备推荐使用Vite创建Vue项目(比Vue CLI更快)npm create vitelatest frontend --template vue cd frontend npm install axios vue-router pinia项目结构建议frontend/ ├─ public/ ├─ src/ │ ├─ api/ # API请求封装 │ ├─ assets/ │ ├─ components/ │ ├─ router/ # 路由配置 │ ├─ stores/ # Pinia状态管理 │ └─ views/ # 页面组件 └─ vite.config.js4. 核心功能实现4.1 RESTful API设计DRF中的视图集(ViewSets)最佳实践# views.py from rest_framework import viewsets class ProductViewSet(viewsets.ModelViewSet): queryset Product.objects.all() serializer_class ProductSerializer def get_queryset(self): queryset super().get_queryset() category self.request.query_params.get(category) if category: queryset queryset.filter(categorycategory) return queryset路由配置优化# urls.py from rest_framework.routers import DefaultRouter router DefaultRouter() router.register(rproducts, ProductViewSet) urlpatterns [ path(api/, include(router.urls)), ]4.2 前端数据交互封装axios实例实现统一错误处理// api/request.js import axios from axios const service axios.create({ baseURL: http://localhost:8000/api, timeout: 5000 }) service.interceptors.response.use( response response.data, error { console.error(API Error:, error.response) return Promise.reject(error) } ) export default service组合式API调用示例// api/product.js import request from ./request export const getProducts (params) request.get(/products, { params }) export const createProduct (data) request.post(/products, data)5. 开发调试技巧5.1 接口调试工具链推荐使用PostmanSwagger的双工具方案安装drf-yasg生成Swagger文档poetry add drf-yasg配置自动API文档# urls.py from drf_yasg.views import get_schema_view from drf_yasg import openapi schema_view get_schema_view( openapi.Info(titleAPI Docs, default_versionv1), publicTrue, ) urlpatterns [ ... path(swagger/, schema_view.with_ui(swagger)), ]5.2 跨域问题深度解决除基本CORS配置外还需注意开发环境下配置代理避免跨域// vite.config.js server: { proxy: { /api: { target: http://localhost:8000, changeOrigin: true, rewrite: path path.replace(/^\/api/, ) } } }生产环境Nginx配置示例location /api { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }6. 项目部署策略6.1 后端部署要点使用GunicornNginx的生产级部署# 安装Gunicorn poetry add gunicorn # 启动命令 gunicorn --bind 0.0.0.0:8000 --workers 4 project.wsgi:application关键Nginx配置location /static/ { alias /path/to/staticfiles/; expires 30d; } location /media/ { alias /path/to/media/; expires 30d; } location /api { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; }6.2 前端部署优化Vite生产构建命令npm run build部署优化建议开启Brotli压缩// vite.config.js import viteCompression from vite-plugin-compression plugins: [ viteCompression({ algorithm: brotliCompress }) ]配置CDN加速静态资源build: { rollupOptions: { output: { chunkFileNames: assets/[hash].js, assetFileNames: assets/[hash][extname] } } }7. 常见问题解决方案7.1 认证与权限控制JWT认证实现方案# settings.py REST_FRAMEWORK { DEFAULT_AUTHENTICATION_CLASSES: ( rest_framework_simplejwt.authentication.JWTTokenUserAuthentication, ) } # urls.py from rest_framework_simplejwt.views import TokenObtainPairView urlpatterns [ path(api/token/, TokenObtainPairView.as_view()), ]前端Token处理// 请求拦截器 service.interceptors.request.use(config { const token localStorage.getItem(access_token) if (token) { config.headers.Authorization Bearer ${token} } return config })7.2 性能优化实践数据库查询优化技巧# 使用select_related减少查询次数 queryset Product.objects.select_related(category).all() # 使用prefetch_related优化多对多关系 queryset Order.objects.prefetch_related(items__product)前端懒加载实现// 路由懒加载 const ProductList () import(../views/ProductList.vue) // 图片懒加载 img v-lazyproduct.image altproduct8. 项目进阶方向8.1 微服务架构演进从单体到微服务的过渡策略先按功能模块拆分API服务引入API Gateway统一入口逐步将共享模型拆分为独立服务8.2 实时功能扩展WebSocket集成方案# 安装Channels poetry add channels # routing.py from channels.routing import ProtocolTypeRouter from django.core.asgi import get_asgi_application application ProtocolTypeRouter({ http: get_asgi_application(), websocket: AuthMiddlewareStack( URLRouter([ path(ws/notifications/, NotificationConsumer.as_asgi()), ]) ), })前端连接示例const socket new WebSocket(ws://localhost:8000/ws/notifications/) socket.onmessage (e) { const data JSON.parse(e.data) // 处理实时通知 }前后端分离开发模式的学习曲线可能会让初学者感到有些陡峭特别是在处理跨域、状态管理和API设计等方面。建议从简单的CRUD功能开始实践逐步添加认证、分页、过滤等复杂功能。在实际项目中保持API文档与代码同步更新是团队协作的关键。