diff --git a/core/forms.py b/core/forms.py index 4dbe1d2..dae4164 100644 --- a/core/forms.py +++ b/core/forms.py @@ -6,7 +6,8 @@ from .models import ( InsightRecord, FamilyTask, TodayPlan, - SystemConfig + SystemConfig, + FamilyMember ) class ReadingRecordForm(forms.ModelForm): @@ -27,8 +28,9 @@ class InsightRecordForm(forms.ModelForm): """感悟记录表单""" class Meta: model = InsightRecord - fields = ['content', 'file'] + fields = ['speaker', 'content', 'file'] widgets = { + 'speaker': forms.Select(attrs={'class': 'form-select'}), 'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 5, 'placeholder': '请输入感悟'}), 'file': forms.FileInput(attrs={'class': 'form-control'}), } @@ -50,9 +52,10 @@ class TodayPlanForm(forms.ModelForm): """今日计划表单""" class Meta: model = TodayPlan - fields = ['date', 'content', 'priority', 'type', 'status'] + fields = ['date', 'speaker', 'content', 'priority', 'type', 'status'] widgets = { 'date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}), + 'speaker': forms.Select(attrs={'class': 'form-select'}), 'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': '请输入计划内容'}), 'priority': forms.Select(attrs={'class': 'form-select'}), 'type': forms.Select(attrs={'class': 'form-select'}), diff --git a/core/migrations/0005_initial_speaker.py b/core/migrations/0005_initial_speaker.py new file mode 100644 index 0000000..96f06f9 --- /dev/null +++ b/core/migrations/0005_initial_speaker.py @@ -0,0 +1,38 @@ +# Generated by Django 5.1.4 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0004_systemconfig_sender_email'), + ] + + operations = [ + migrations.CreateModel( + name='FamilyMember', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=20, unique=True, verbose_name='姓名')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ], + options={ + 'verbose_name': '家庭成员', + 'verbose_name_plural': '家庭成员', + 'ordering': ['name'], + }, + ), + migrations.AddField( + model_name='insightrecord', + name='speaker', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.familymember', verbose_name='发言人'), + ), + migrations.AddField( + model_name='todayplan', + name='speaker', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.familymember', verbose_name='发言人'), + ), + ] diff --git a/core/models.py b/core/models.py index 67deb5b..394787e 100644 --- a/core/models.py +++ b/core/models.py @@ -71,6 +71,20 @@ class PlanType(models.Model): def __str__(self): return self.name +class FamilyMember(models.Model): + """家庭成员""" + name = models.CharField(max_length=20, unique=True, 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 = "家庭成员" + ordering = ['name'] + + def __str__(self): + return self.name + class ReadingRecord(models.Model): """阅读记录表""" date = models.DateField(default=timezone.now, verbose_name="日期") @@ -95,6 +109,7 @@ class InsightRecord(models.Model): """感悟记录表""" date = models.DateField(default=timezone.now, verbose_name="日期") content = models.TextField(verbose_name="内容") + speaker = models.ForeignKey(FamilyMember, on_delete=models.CASCADE, verbose_name="发言人") file = models.FileField(upload_to='insight_files/', blank=True, null=True, verbose_name="上传文件") created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间") @@ -129,6 +144,7 @@ class TodayPlan(models.Model): """今日计划表""" date = models.DateField(default=timezone.now, verbose_name="日期") content = models.TextField(verbose_name="内容") + speaker = models.ForeignKey(FamilyMember, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="发言人") priority = models.ForeignKey(Priority, on_delete=models.CASCADE, default=2, verbose_name="优先级") type = models.ForeignKey(PlanType, on_delete=models.CASCADE, default=4, verbose_name="类型") status = models.ForeignKey(Status, on_delete=models.CASCADE, default=1, verbose_name="状态") diff --git a/core/templates/core/report_pdf.html b/core/templates/core/report_pdf.html index ada7ff5..85f9a08 100644 --- a/core/templates/core/report_pdf.html +++ b/core/templates/core/report_pdf.html @@ -133,7 +133,7 @@ {% if yesterday_insight %}
| 发言人 | 类型 | 内容 | 优先级 | @@ -157,6 +158,7 @@
|---|---|---|---|
| {{ plan.speaker.name }} | {{ plan.get_type_display }} | {{ plan.content }} | {{ plan.get_priority_display }} | diff --git a/core/views.py b/core/views.py index b87c1fe..148e1cb 100644 --- a/core/views.py +++ b/core/views.py @@ -39,7 +39,8 @@ from .models import ( InsightRecord, FamilyTask, TodayPlan, - SystemConfig + SystemConfig, + FamilyMember ) from .forms import ( ReadingRecordForm, @@ -147,6 +148,7 @@ def delete_reading(request, pk): # 添加感悟记录 def add_insight(request): """添加感悟记录""" + family_members = FamilyMember.objects.all() if request.method == 'POST': form = InsightRecordForm(request.POST, request.FILES) if form.is_valid(): @@ -158,13 +160,14 @@ def add_insight(request): else: form = InsightRecordForm() - context = {'form': form} + context = {'form': form, 'family_members': family_members} return render(request, 'core/add_insight.html', context) # 编辑感悟记录 def edit_insight(request, pk): """编辑感悟记录""" insight = get_object_or_404(InsightRecord, pk=pk) + family_members = FamilyMember.objects.all() if request.method == 'POST': form = InsightRecordForm(request.POST, request.FILES, instance=insight) if form.is_valid(): @@ -174,7 +177,7 @@ def edit_insight(request, pk): else: form = InsightRecordForm(instance=insight) - context = {'form': form, 'insight': insight} + context = {'form': form, 'insight': insight, 'family_members': family_members} return render(request, 'core/edit_insight.html', context) # 删除感悟记录 @@ -257,6 +260,7 @@ def delete_today_reading(request, pk): # 添加今日感悟记录 def add_today_insight(request): """添加今日感悟记录""" + family_members = FamilyMember.objects.all() if request.method == 'POST': form = InsightRecordForm(request.POST, request.FILES) if form.is_valid(): @@ -268,13 +272,14 @@ def add_today_insight(request): else: form = InsightRecordForm() - context = {'form': form} + context = {'form': form, 'family_members': family_members} return render(request, 'core/add_insight.html', context) # 编辑今日感悟记录 def edit_today_insight(request, pk): """编辑今日感悟记录""" insight = get_object_or_404(InsightRecord, pk=pk) + family_members = FamilyMember.objects.all() if request.method == 'POST': form = InsightRecordForm(request.POST, request.FILES, instance=insight) if form.is_valid(): @@ -284,7 +289,7 @@ def edit_today_insight(request, pk): else: form = InsightRecordForm(instance=insight) - context = {'form': form, 'insight': insight} + context = {'form': form, 'insight': insight, 'family_members': family_members} return render(request, 'core/edit_insight.html', context) # 删除今日感悟记录 @@ -373,6 +378,7 @@ def today_plan(request): # 添加今日计划 def add_today_plan(request): """添加今日计划""" + family_members = FamilyMember.objects.all() if request.method == 'POST': form = TodayPlanForm(request.POST) if form.is_valid(): @@ -382,13 +388,14 @@ def add_today_plan(request): else: form = TodayPlanForm() - context = {'form': form} + context = {'form': form, 'family_members': family_members} return render(request, 'core/add_today_plan.html', context) # 编辑今日计划 def edit_today_plan(request, pk): """编辑今日计划""" plan = get_object_or_404(TodayPlan, pk=pk) + family_members = FamilyMember.objects.all() if request.method == 'POST': form = TodayPlanForm(request.POST, instance=plan) if form.is_valid(): @@ -398,7 +405,7 @@ def edit_today_plan(request, pk): else: form = TodayPlanForm(instance=plan) - context = {'form': form, 'plan': plan} + context = {'form': form, 'plan': plan, 'family_members': family_members} return render(request, 'core/edit_today_plan.html', context) # 删除今日计划 diff --git a/update_db.py b/update_db.py new file mode 100644 index 0000000..4faf067 --- /dev/null +++ b/update_db.py @@ -0,0 +1,22 @@ +import sqlite3 + +conn = sqlite3.connect('db.sqlite3') +cursor = conn.cursor() + +cursor.execute(''' +INSERT INTO core_familymember (name, created_at, updated_at) +VALUES ('默认成员', datetime('now', 'localtime'), datetime('now', 'localtime')); +''') + +cursor.execute(''' +ALTER TABLE core_insightrecord ADD COLUMN speaker_id INTEGER NOT NULL DEFAULT 1; +''') + +cursor.execute(''' +ALTER TABLE core_todayplan ADD COLUMN speaker_id INTEGER NOT NULL DEFAULT 1; +''') + +conn.commit() +conn.close() + +print("Database updated successfully!") diff --git a/verify_db.py b/verify_db.py new file mode 100644 index 0000000..dc780eb --- /dev/null +++ b/verify_db.py @@ -0,0 +1,10 @@ +import sqlite3 +conn = sqlite3.connect('db.sqlite3') +cursor = conn.cursor() +cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'core_%' ORDER BY name;") +print("Tables:", [r[0] for r in cursor.fetchall()]) +cursor.execute("SELECT COUNT(*) FROM core_familymember;") +print("Family members count:", cursor.fetchone()[0]) +cursor.execute("SELECT sql FROM sqlite_master WHERE type='table' AND name='core_insightrecord';") +print("InsightRecord schema:", cursor.fetchone()[0]) +conn.close()