这个项目是一个典型的全栈Web开发实践,采用前后端分离架构构建个人博客系统。前端使用Vue.js实现动态交互界面,后端选用Flask轻量级框架提供API服务,同时结合PyCharm作为主力开发工具。有趣的是,虽然标题中提到了Django,但实际核心框架是Flask,这种技术选型的对比与取舍本身就值得深入探讨。
我在实际开发中发现,这种技术组合特别适合个人开发者快速搭建中小型内容平台。Flask的灵活性让后端API开发变得高效,Vue的组件化开发则让前端维护成本大幅降低。整个项目从零开始到部署上线,大约需要40-50个有效工时,适合有一定Python和JavaScript基础的开发者练手。
Flask作为轻量级Python Web框架,其微内核设计特别适合博客类应用。核心配置只需要几行代码:
python复制from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Hello Blog!'
但在实际项目中,我们需要扩展更多功能模块。推荐使用以下关键扩展:
重要提示:Flask的蓝图(Blueprint)功能一定要善用,它能让项目结构保持清晰。我的经验是按功能模块划分蓝图,比如
auth_bp、post_bp等,每个蓝图有自己的路由、模板和静态文件。
前端采用Vue 3的组合式API开发,项目结构建议如下:
code复制/src
/assets
/components
BlogHeader.vue
PostList.vue
/views
HomeView.vue
PostView.vue
/router
/store
App.vue
main.js
关键实现技巧:
/post/:idPyCharm作为主力IDE,有几个必装的插件:
调试技巧:
后端模型设计:
python复制class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def to_dict(self):
return {
'id': self.id,
'title': self.title,
'content': self.content,
'created_at': self.created_at.isoformat()
}
API接口设计:
python复制class PostAPI(Resource):
def get(self, post_id=None):
if post_id:
post = Post.query.get_or_404(post_id)
return post.to_dict()
posts = Post.query.order_by(Post.created_at.desc()).all()
return [p.to_dict() for p in posts]
@login_required
def post(self):
data = request.get_json()
post = Post(
title=data['title'],
content=data['content'],
author_id=current_user.id
)
db.session.add(post)
db.session.commit()
return post.to_dict(), 201
前端使用vue-markdown-editor组件:
vue复制<template>
<div>
<v-md-editor
v-model="content"
height="500px"
@upload-image="handleUploadImage"
></v-md-editor>
</div>
</template>
<script>
import VMdEditor from '@kangc/v-md-editor';
import '@kangc/v-md-editor/lib/style/base-editor.css';
export default {
components: {
VMdEditor
},
data() {
return {
content: ''
}
},
methods: {
handleUploadImage(event, insertImage) {
// 实现图片上传逻辑
}
}
}
</script>
JWT认证实现流程:
python复制from flask_jwt_extended import create_access_token
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
user = User.query.filter_by(username=username).first()
if user and user.check_password(password):
access_token = create_access_token(identity=username)
return {'access_token': access_token}
return {'error': 'Invalid credentials'}, 401
javascript复制axios.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
}, error => {
return Promise.reject(error)
})
推荐部署架构:
Nginx配置示例:
nginx复制server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static {
alias /path/to/your/static/files;
expires 30d;
}
}
启动Gunicorn:
bash复制gunicorn -w 4 -b 127.0.0.1:8000 wsgi:app
数据库优化:
前端优化:
Flask后端配置CORS:
python复制from flask_cors import CORS
CORS(app, resources={
r"/api/*": {
"origins": ["http://localhost:8080"],
"methods": ["GET", "POST", "PUT", "DELETE"],
"allow_headers": ["Content-Type", "Authorization"]
}
})
开发环境配置:
python复制if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, static_url_path='', static_folder='static')
生产环境建议:
使用Flask-Migrate的正确姿势:
bash复制# 初始化迁移仓库
flask db init
# 生成迁移脚本
flask db migrate -m "initial migration"
# 应用迁移
flask db upgrade
遇到迁移冲突时:
flask db stamp标记特定版本实现方案:
数据结构设计:
python复制tags = db.Table('tags',
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
db.Column('post_id', db.Integer, db.ForeignKey('post.id'))
)
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), unique=True)
posts = db.relationship('Post', secondary=tags, backref=db.backref('tags', lazy='dynamic'))
以GitHub OAuth为例:
这个项目最让我有成就感的是看到前后端完美协作的那一刻。当Vue组件成功获取Flask API的数据并优雅地渲染出来时,那种全栈开发的满足感是无可替代的。建议每个功能模块开发完成后都做一个完整的测试流程,从数据库操作到API响应再到前端展示,确保整个链路畅通无阻。