commit c8e8becffc00f1453557ec38c1079b88eb9f5830 Author: ethan.chen Date: Mon May 19 17:06:35 2025 +0800 chore:初始化,数据库处理 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f20c020 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual Environment +venv/ +ENV/ + +# Database +*.db +*.sqlite3 + +# Logs +*.log + +# Mac +.DS_Store + +# Editor +.vscode/ +.idea/ +*.swp diff --git a/README.md b/README.md new file mode 100644 index 0000000..f670bbe --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# 个人媒体记录应用 - 后端 + +这是一个使用 Flask 和 SQLite 构建的后端服务,用于管理个人媒体记录(游戏、书籍、电影、番剧等)。 + +## 环境要求 + +- Python 3.8+ +- pip(Python 包管理器) + +## 安装步骤 + +1. 创建虚拟环境(推荐): +```bash +python -m venv venv +source venv/bin/activate # 在 Windows 上使用 venv\Scripts\activate +``` + +2. 安装依赖: +```bash +pip install -r requirements.txt +``` + +## 运行服务 + +```bash +python app.py +``` + +服务将在 http://localhost:5000 上运行。 + +## API 端点 + +- GET /api/media - 获取所有媒体记录 +- POST /api/media - 创建新的媒体记录 +- PUT /api/media/ - 更新指定 ID 的媒体记录 +- DELETE /api/media/ - 删除指定 ID 的媒体记录 + +## 数据模型 + +Media 模型包含以下字段: +- id: 主键 +- title: 标题 +- type: 类型(game/book/movie/anime) +- status: 状态(completed/in_progress/plan_to_watch) +- rating: 评分 +- notes: 笔记 +- created_at: 创建时间 +- updated_at: 更新时间 \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..63f1e0b --- /dev/null +++ b/app.py @@ -0,0 +1,112 @@ +from flask import Flask, request, jsonify +from flask_sqlalchemy import SQLAlchemy +from flask_cors import CORS +from datetime import datetime +import os + +app = Flask(__name__) +CORS(app) + +# 配置数据库 +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///media.db' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +db = SQLAlchemy(app) + +# 定义数据模型 +class Media(db.Model): + id = db.Column(db.Integer, primary_key=True) + title = db.Column(db.String(200), nullable=False) + type = db.Column(db.String(50), nullable=False) # game, book, movie, anime, other + status = db.Column(db.String(50), nullable=False) # completed, in_progress, plan_to_watch + rating = db.Column(db.Float) + notes = db.Column(db.Text) + platform = db.Column(db.String(100)) # 平台信息 + date = db.Column(db.Date) # 完成/观看日期 + created_at = db.Column(db.DateTime, default=datetime.utcnow) + updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) + +# 创建所有数据库表 +with app.app_context(): + db.create_all() + +# API 路由 +@app.route('/api/media', methods=['GET']) +def get_all_media(): + media_list = Media.query.all() + return jsonify([{ + 'id': media.id, + 'title': media.title, + 'type': media.type, + 'status': media.status, + 'rating': media.rating, + 'notes': media.notes, + 'platform': media.platform, + 'date': media.date.isoformat() if media.date else None, + 'created_at': media.created_at.isoformat(), + 'updated_at': media.updated_at.isoformat() + } for media in media_list]) + +@app.route('/api/media', methods=['POST']) +def create_media(): + data = request.json + new_media = Media( + title=data['title'], + type=data['type'], + status=data['status'], + rating=data.get('rating'), + notes=data.get('notes'), + platform=data.get('platform'), + date=datetime.strptime(data['date'], '%Y-%m-%d').date() if data.get('date') else None + ) + db.session.add(new_media) + db.session.commit() + return jsonify({ + 'id': new_media.id, + 'title': new_media.title, + 'type': new_media.type, + 'status': new_media.status, + 'rating': new_media.rating, + 'notes': new_media.notes, + 'platform': new_media.platform, + 'date': new_media.date.isoformat() if new_media.date else None, + 'created_at': new_media.created_at.isoformat(), + 'updated_at': new_media.updated_at.isoformat() + }), 201 + +@app.route('/api/media/', methods=['PUT']) +def update_media(media_id): + media = Media.query.get_or_404(media_id) + data = request.json + + media.title = data.get('title', media.title) + media.type = data.get('type', media.type) + media.status = data.get('status', media.status) + media.rating = data.get('rating', media.rating) + media.notes = data.get('notes', media.notes) + media.platform = data.get('platform', media.platform) + if data.get('date'): + media.date = datetime.strptime(data['date'], '%Y-%m-%d').date() + + db.session.commit() + return jsonify({ + 'id': media.id, + 'title': media.title, + 'type': media.type, + 'status': media.status, + 'rating': media.rating, + 'notes': media.notes, + 'platform': media.platform, + 'date': media.date.isoformat() if media.date else None, + 'created_at': media.created_at.isoformat(), + 'updated_at': media.updated_at.isoformat() + }) + +@app.route('/api/media/', methods=['DELETE']) +def delete_media(media_id): + media = Media.query.get_or_404(media_id) + db.session.delete(media) + db.session.commit() + return '', 204 + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..28f7603 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +Flask==3.0.2 +Flask-SQLAlchemy==3.1.1 +Flask-Cors==4.0.0 +python-dotenv==1.0.1 +SQLAlchemy==2.0.28 \ No newline at end of file