Files
diary-family/README.md

636 lines
17 KiB
Markdown
Raw Normal View History

2026-01-04 19:21:52 +08:00
# 家庭日报系统
专注于家庭生活的轻量级日报系统使用Django框架开发。
2026-01-04 19:21:52 +08:00
## 功能特性
2026-01-04 19:21:52 +08:00
2026-01-07 21:37:18 +08:00
- 阅读记录管理(支持添加阅读笔记)
- 感悟记录管理
2026-01-07 21:37:18 +08:00
- 家庭事项管理(支持自定义事项类型)
- 今日计划管理
- 报告生成
- 邮件发送
2026-01-07 21:37:18 +08:00
- 后台管理界面(访问路径:/houtai
2026-01-04 19:21:52 +08:00
## 技术栈
2026-01-04 19:21:52 +08:00
- Python 3.10+
- Django 4.2+
- Bootstrap 5
- SQLite开发环境
- PostgreSQL/MySQL生产环境
- Gunicorn + Nginx生产部署
2026-01-04 19:21:52 +08:00
## 快速开始
2026-01-04 19:21:52 +08:00
### 安装依赖
```bash
pip install -r requirements.txt
```
### 运行开发服务器
2026-01-04 19:21:52 +08:00
```bash
python manage.py runserver
```
### 访问系统
打开浏览器访问http://127.0.0.1:8000
2026-01-04 19:21:52 +08:00
## 数据库迁移指南
2026-01-04 19:21:52 +08:00
### 基本迁移流程
2026-01-04 19:21:52 +08:00
1. 生成迁移文件:
```bash
python manage.py makemigrations
```
2026-01-05 21:33:18 +08:00
2. 查看迁移文件内容(重要!):
```bash
cat core/migrations/000x_xxx.py
```
2026-01-05 21:33:18 +08:00
3. 应用迁移:
```bash
python manage.py migrate
```
2026-01-05 21:33:18 +08:00
### 当数据库有数据时增加字段
2026-01-05 21:33:18 +08:00
#### 问题说明
2026-01-05 21:33:18 +08:00
当数据库中已有数据时通过Django的migrate命令增加新字段**不会删除原有数据**,但需要注意以下几点:
2026-01-05 21:33:18 +08:00
1. 如果新字段设置为**非空**`null=False, blank=False`),则必须提供默认值,否则迁移会失败
2. 如果新字段设置为**可空**`null=True, blank=True`则迁移会自动执行原有记录的新字段值为NULL
2026-01-05 21:33:18 +08:00
#### 正确部署流程
2026-01-05 21:33:18 +08:00
1. **在开发环境测试**
- 首先在开发环境生成迁移文件
- 检查迁移文件内容,确保:
- 新字段设置为可空(`null=True, blank=True`),或者
- 新字段提供了合理的默认值
- 在开发环境执行迁移,测试功能是否正常
2026-01-05 21:33:18 +08:00
2. **备份生产数据库**(重要!):
```bash
# PostgreSQL示例
pg_dump -U username -d dbname > backup_$(date +%Y%m%d_%H%M%S).sql
# MySQL示例
mysqldump -u username -p dbname > backup_$(date +%Y%m%d_%H%M%S).sql
```
2026-01-05 21:33:18 +08:00
3. **在生产环境执行迁移**
```bash
# 进入项目目录
cd /path/to/diary-family
# 激活虚拟环境
source venv/bin/activate
# 生成迁移文件(如果在开发环境已生成,可跳过)
python manage.py makemigrations
# 应用迁移
python manage.py migrate
```
2026-01-05 21:33:18 +08:00
4. **验证迁移结果**
- 检查应用是否正常运行
- 验证新功能是否可用
- 检查数据是否完整
2026-01-05 21:33:18 +08:00
#### 示例增加阅读笔记note字段
2026-01-05 21:33:18 +08:00
1. 在模型中添加字段(`core/models.py`
```python
# 正确的做法:设置为可空字段
note = models.TextField(blank=True, null=True, verbose_name="阅读笔记")
# 或者:提供默认值
note = models.TextField(default="", blank=True, verbose_name="阅读笔记")
```
2026-01-05 21:33:18 +08:00
2. 生成迁移文件:
```bash
python manage.py makemigrations
```
2026-01-05 21:33:18 +08:00
3. 检查迁移文件,确保新字段设置正确:
```python
# 迁移文件示例0003_readingrecord_note.py
class Migration(migrations.Migration):
dependencies = [
('core', '0002_xxx'),
]
operations = [
migrations.AddField(
model_name='readingrecord',
name='note',
field=models.TextField(blank=True, null=True, verbose_name='阅读笔记'),
),
]
```
2026-01-05 21:33:18 +08:00
4. 应用迁移:
```bash
python manage.py migrate
```
2026-01-05 21:33:18 +08:00
## CSV数据导入指南
### 生成CSV文件
项目包含一个`generate_import_csv.py`脚本用于生成符合数据库表结构的CSV文件并导入数据。
1. 生成CSV文件
```bash
python generate_import_csv.py
```
2. 生成的CSV文件
- `reading_type.csv` - 阅读记录类型
- `insight_record.csv` - 感悟记录
- `reading_record.csv` - 阅读记录
### CSV文件格式说明
#### reading_type.csv阅读记录类型
| 字段名 | 类型 | 说明 |
|-------|------|------|
| name | 字符串 | 阅读类型名称(如:书籍、文章、论文等) |
#### insight_record.csv感悟记录
| 字段名 | 类型 | 说明 |
|-------|------|------|
| date | 日期 | 记录日期格式YYYY-MM-DD |
| content | 文本 | 感悟内容 |
#### reading_record.csv阅读记录
| 字段名 | 类型 | 说明 |
|-------|------|------|
| date | 日期 | 记录日期格式YYYY-MM-DD |
| type_id | 整数 | 阅读类型ID关联reading_type表的id字段 |
| title | 字符串 | 阅读标题 |
| source | 字符串 | 阅读来源 |
| progress | 字符串 | 阅读进度(如:已完成、进行中、未开始) |
| note | 文本 | 阅读笔记 |
### 自定义CSV数据
你可以手动编辑生成的CSV文件添加或修改数据然后再次运行导入脚本将数据导入到数据库。
### 数据导入
脚本会自动将CSV数据导入到数据库中导入流程
1. 清空ReadingType表的现有数据避免类型ID冲突
2. 导入ReadingType数据
3. 导入InsightRecord数据
4. 导入ReadingRecord数据
### 验证导入结果
可以使用Django shell查询数据库验证数据是否正确导入
```bash
python -c "import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'diary_family.settings'); import django; django.setup(); from core.models import ReadingType, InsightRecord, ReadingRecord; print('ReadingType数量:', ReadingType.objects.count()); print('InsightRecord数量:', InsightRecord.objects.count()); print('ReadingRecord数量:', ReadingRecord.objects.count()); print('ReadingType数据:', [rt.name for rt in ReadingType.objects.all()])"
```
## 生产部署
2026-01-04 19:21:52 +08:00
### 使用Gunicorn + Nginx
2026-01-04 19:21:52 +08:00
1. 安装Gunicorn
```bash
pip install gunicorn
```
2026-01-04 19:21:52 +08:00
2. 启动Gunicorn
2026-01-04 19:21:52 +08:00
```bash
gunicorn diary_family.wsgi:application --bind 0.0.0.0:8000
2026-01-04 19:21:52 +08:00
```
3. 配置Nginx`/etc/nginx/sites-available/diary-family`
```nginx
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static/ {
alias /path/to/diary-family/static/;
}
location /media/ {
alias /path/to/diary-family/media/;
}
}
```
2026-01-04 19:21:52 +08:00
4. 启用Nginx配置
```bash
ln -s /etc/nginx/sites-available/diary-family /etc/nginx/sites-enabled/
systemctl restart nginx
```
2026-01-04 19:21:52 +08:00
2026-01-07 21:37:18 +08:00
## 常规代码更新流程
当需要更新代码时,可以使用以下命令:
退出虚拟环境
deactivate
2026-01-07 21:37:18 +08:00
```bash
cd /var/www/diary-family
# 1. 拉取远程最新代码(只获取,不合并)
git fetch origin
# 2. 硬重置本地分支到远程分支的最新版本(会覆盖所有本地未提交修改)
# 注意:将 main 替换为你的分支名(如 master、dev 等)
git reset --hard origin/main
# 3. 激活虚拟环境
source venv/bin/activate
# 4. 安装新依赖(如果有)
pip install -r requirements.txt
# 5. 收集静态文件(如果有静态文件更新)
python manage.py collectstatic --noinput
# 6. 重启服务
sudo supervisorctl restart all
sudo systemctl restart nginx
```
## 系统配置
2026-01-04 19:21:52 +08:00
在系统配置页面可以设置:
- SMTP服务器信息
- 邮件发送时间
- 收件人邮箱
2026-01-04 19:21:52 +08:00
## Celery 定时发送邮件任务配置
### 1. 邮件配置设置
在系统配置页面设置完邮件信息后,还需要在 Django 项目的 settings.py 中添加基础邮件配置:
```python
# 邮件基础配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_PORT = 587 # 或根据你的 SMTP 服务器设置
EMAIL_USE_TLS = True # 或根据你的 SMTP 服务器设置
```
### 2. 启动 Celery Worker 和 Beat
#### 开发环境
```bash
# 启动 Celery Worker
celery -A diary_family worker -l info
# 启动 Celery Beat用于定时任务调度
celery -A diary_family beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
```
#### 生产环境
建议使用 supervisor 管理 Celery 进程。创建两个 supervisor 配置文件:
1. **celery_worker.conf**
```ini
[program:celery_worker]
command=/path/to/venv/bin/celery -A diary_family worker -l info
directory=/path/to/diary-family
user=www-data
group=www-data
autostart=true
autorestart=true
stdout_logfile=/var/log/celery/worker.log
stderr_logfile=/var/log/celery/worker_error.log
```
2. **celery_beat.conf**
```ini
[program:celery_beat]
command=/path/to/venv/bin/celery -A diary_family beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
directory=/path/to/diary-family
user=www-data
group=www-data
autostart=true
autorestart=true
stdout_logfile=/var/log/celery/beat.log
stderr_logfile=/var/log/celery/beat_error.log
```
启动 supervisor 服务:
```bash
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start celery_worker
sudo supervisorctl start celery_beat
```
### 3. 配置定时任务
系统使用 `django_celery_beat` 进行定时任务管理,支持两种方式配置:
#### 方式一:通过 Django 管理后台(推荐)
1. 登录 Django 管理后台(/houtai
2. 找到 **Periodic tasks**(周期性任务)
3. 点击 **Add** 按钮添加新任务
4. 配置任务:
- **Name**: 任务名称(如:每日报告发送)
- **Task (registered)**: 选择 `core.tasks.send_daily_report`
- **Interval**: 设置执行间隔(如:每天)
- **Enabled**: 勾选启用
5. 点击 **Save** 保存
#### 方式二:通过代码配置
`core/tasks.py` 中添加定时任务配置:
```python
from celery import shared_task
from django_celery_beat.models import PeriodicTask, IntervalSchedule
# 创建或更新定时任务
def setup_daily_report_task():
# 创建每天执行的间隔
schedule, created = IntervalSchedule.objects.get_or_create(
every=1,
period=IntervalSchedule.DAYS,
)
# 创建或更新定时任务
task, created = PeriodicTask.objects.update_or_create(
name='Daily Report Task',
defaults={
'interval': schedule,
'task': 'core.tasks.send_daily_report',
},
)
return task
```
然后在 Django 启动时调用此函数(如在 `core/apps.py` 中)。
### 4. 验证任务执行
- 查看 Celery 日志:`tail -f /var/log/celery/worker.log`
- 检查邮件是否正常发送
- 在 Django 管理后台查看任务执行记录
2026-01-10 18:08:34 +08:00
### 5. 日志文件不存在问题解决方法
如果在生产服务器上执行 `tail -f /var/log/celery/worker.log` 时提示 `No such file or directory`,请按照以下步骤解决:
#### 步骤1检查日志目录是否存在
```bash
# 检查日志目录是否存在
ls -la /var/log/celery/
# 如果目录不存在,创建目录
sudo mkdir -p /var/log/celery/
# 设置正确的权限(确保 Celery 进程用户有读写权限)
sudo chown -R www-data:www-data /var/log/celery/
sudo chmod -R 755 /var/log/celery/
```
#### 步骤2检查 Supervisor 配置
确保 Supervisor 配置文件中指定的日志路径正确,并且 Celery 进程用户对该路径有读写权限。
#### 步骤3重启 Supervisor 和 Celery
```bash
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl restart celery_worker celery_beat
```
### 6. 试运行周期任务
当设置一个周期任务后,您可以通过以下方式试运行任务,而不需要等待到指定的时间:
#### 方式1通过 Django 管理后台
1. 登录 Django 管理后台(/houtai
2. 找到 **Periodic tasks**(周期性任务)
3. 选择您创建的任务
4. 点击页面底部的 **Run Task** 按钮立即执行任务
#### 方式2通过命令行
```bash
# 直接调用任务函数(同步执行)
python manage.py shell -c "from core.tasks import generate_daily_pdf_report; generate_daily_pdf_report()"
# 或者使用 Celery 命令行工具
celery -A diary_family call core.tasks.generate_daily_pdf_report
```
#### 方式3使用测试脚本
项目提供了一个测试脚本,用于验证 Celery 任务是否可以正常运行:
```bash
# 运行测试脚本
python test_celery.py
```
### 7. 常见错误和解决方法
#### 错误1日志文件不存在
**错误信息**`tail: cannot open '/var/log/celery/worker.log' for reading: No such file or directory`
**解决方法**
- 按照步骤5中的说明创建日志目录并设置正确权限
- 检查 Supervisor 配置中的日志路径是否正确
- 重启 Supervisor 和 Celery 服务
#### 错误2Celery 无法连接到 Redis
**错误信息**`redis.exceptions.ConnectionError: Error 111 connecting to localhost:6379. Connection refused.`
**解决方法**
- 检查 Redis 服务是否正常运行:`sudo systemctl status redis-server`
- 启动 Redis 服务:`sudo systemctl start redis-server`
- 检查 Redis 配置是否允许本地连接
#### 错误3任务执行失败
**错误信息**`Task core.tasks.generate_daily_pdf_report[xxx] raised unexpected: Exception(...)`
**解决方法**
- 查看详细日志:`tail -f /var/log/celery/worker.log`
- 检查任务代码中的错误
- 确保所有依赖库都已正确安装
- 检查相关服务如数据库、Redis是否正常运行
#### 错误4PDF 生成失败
**错误信息**`WeasyPrint库不可用无法生成PDF报告`
**解决方法**
- 安装 WeasyPrint 库:`pip install weasyprint`
- 对于 Ubuntu 系统,可能需要安装系统依赖:
```bash
sudo apt-get install -y libpango-1.0-0 libpangoft2-1.0-0
```
### 8. 常见问题排查
1. **任务不执行**
- 检查 Celery worker 和 beat 是否正常运行
- 检查 Redis 服务是否正常
- 检查任务是否已启用
- 检查系统时间是否正确
2. **邮件发送失败**
- 检查 SMTP 服务器配置是否正确
- 检查邮箱账号密码是否正确
- 检查收件人邮箱格式是否正确
- 查看 Celery 日志中的错误信息
3. **任务执行延迟**
- 检查系统负载是否过高
- 考虑增加 Celery worker 数量
- 检查 Redis 性能
### 6. 生产环境优化建议
- 使用独立的 Redis 服务器
- 配置合适的 worker 数量建议CPU 核心数 × 2
- 定期清理 Celery 任务结果
- 配置监控系统(如 Prometheus + Grafana
- 启用 Celery 监控工具(如 Flower
## 定时生成PDF文件配置
除了定时发送邮件外系统还支持单独定时生成PDF文件便于在服务器上保存历史报告。
### 1. 配置定时生成PDF任务
#### 方式一:通过 Django 管理后台(推荐)
1. 登录 Django 管理后台(/houtai
2. 找到 **Periodic tasks**(周期性任务)
3. 点击 **Add** 按钮添加新任务
4. 配置任务:
- **Name**: 任务名称每日PDF报告生成
- **Task (registered)**: 选择 `core.tasks.generate_daily_pdf_report`
- **Interval**: 设置执行间隔(如:每天)
- **Enabled**: 勾选启用
5. 点击 **Save** 保存
#### 方式二:通过代码配置
`core/tasks.py` 中添加定时任务配置:
```python
from celery import shared_task
from django_celery_beat.models import PeriodicTask, IntervalSchedule
# 创建或更新PDF生成定时任务
def setup_daily_pdf_task():
# 创建每天执行的间隔
schedule, created = IntervalSchedule.objects.get_or_create(
every=1,
period=IntervalSchedule.DAYS,
)
# 创建或更新定时任务
task, created = PeriodicTask.objects.update_or_create(
name='Daily PDF Generation Task',
defaults={
'interval': schedule,
'task': 'core.tasks.generate_daily_pdf_report',
},
)
return task
```
然后在 Django 启动时调用此函数(如在 `core/apps.py` 中)。
### 2. PDF文件存储位置
生成的PDF文件默认存储在项目的 `reports` 目录下,命名格式为 `report_YYYY-MM-DD.pdf`
可以在 `settings.py` 中修改存储位置:
```python
# Reports files configuration
REPORTS_URL = '/reports/'
REPORTS_ROOT = BASE_DIR / 'reports' # 可以修改为其他路径
```
### 3. 验证PDF生成任务
- 查看 Celery 日志:`tail -f /var/log/celery/worker.log`
- 检查PDF文件是否生成`ls -la /path/to/diary-family/reports/`
- 在 Django 管理后台查看任务执行记录
### 4. 常见问题排查
1. **PDF生成失败**
- 检查 WeasyPrint 库是否正确安装:`pip list | grep weasyprint`
- 检查系统字体是否完整PDF生成需要系统字体支持
- 查看 Celery 日志中的错误信息
2. **任务执行但没有生成文件**
- 检查 `REPORTS_ROOT` 目录权限:确保 Celery 进程有写入权限
- 检查磁盘空间是否充足
- 查看 Celery 日志中的详细信息
3. **PDF内容不完整**
- 检查模板文件 `core/templates/core/report_pdf.html` 是否完整
- 确保所有依赖的 CSS 和图像资源都能正常访问
## Celery 监控(可选)
使用 Flower 监控 Celery 任务:
```bash
# 安装 Flower
pip install flower
# 启动 Flower
celery -A diary_family flower --port=5555
```
访问 http://your-server:5555 查看任务监控界面。
## 注意事项
2026-01-04 19:21:52 +08:00
1. 定期备份数据库
2. 生产环境建议使用PostgreSQL或MySQL数据库
3. 定期清理过期数据
4. 保持依赖包更新
2026-01-04 19:21:52 +08:00
## 许可证
2026-01-04 19:21:52 +08:00
MIT License