Files
openclaw-monitor/code/backend/lobsters/models.py
flying-hero 24e4ca2c82 feat: 创建 LobsterDiary 模型,支持数据库存储日记
- 创建 LobsterDiary 模型
  * 关联龙虾(ForeignKey)
  * 日期、标题、内容
  * 分类(成才之路/工作记忆/技术笔记)
  * 标签(JSONField)
  * Embedding 字段(预留 RAG 支持)
  * 数据库索引优化

- 数据库迁移
  * 添加 LobsterDiary 表
  * 添加索引:lobster+date, category+date, date

- 导入脚本
  * 创建 import_diaries 管理命令
  * 导入飞行侠的成才之路日记(3 篇)

- 更新 API
  * /api/lobsters/<id>/diary/dates/ - 从数据库查询
  * /api/lobsters/<id>/diary/<date>/ - 从数据库读取

- PostgreSQL 配置模板
  * settings_postgresql.py
  * 准备好 PostgreSQL 迁移

技术栈:SQLite(当前) → PostgreSQL(未来)
RAG 支持:预留 embedding 字段,未来可扩展

🗄️ 日记正式进入数据库时代!
2026-04-03 17:38:18 +08:00

95 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from django.db import models
from django.utils import timezone
class Lobster(models.Model):
"""龙虾模型"""
name = models.CharField(max_length=50, verbose_name='名称')
emoji = models.CharField(max_length=10, verbose_name='Emoji')
port = models.IntegerField(verbose_name='端口')
specialty = models.CharField(max_length=100, verbose_name='专长')
container = models.CharField(max_length=100, verbose_name='容器')
app_name = models.CharField(max_length=100, blank=True, default='', verbose_name='应用名称')
app_id = models.CharField(max_length=50, blank=True, default='', verbose_name='应用 ID')
workspace = models.CharField(max_length=100, blank=True, default='', 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 = ['id']
def __str__(self):
return f'{self.emoji} {self.name}'
class LobsterDiary(models.Model):
"""龙虾日记模型(支持 RAG"""
# 分类选择
CATEGORY_CHOICES = [
('chengcai', '成才之路'),
('memory', '工作记忆'),
('tech', '技术笔记'),
('other', '其他'),
]
# 关联龙虾
lobster = models.ForeignKey(
Lobster,
on_delete=models.CASCADE,
related_name='diaries',
verbose_name='龙虾'
)
# 基本信息
date = models.DateField(verbose_name='日期')
title = models.CharField(max_length=200, verbose_name='标题')
content = models.TextField(verbose_name='内容')
# 分类和标签RAG 检索的关键元数据)
category = models.CharField(
max_length=50,
choices=CATEGORY_CHOICES,
default='other',
verbose_name='分类'
)
tags = models.JSONField(default=list, blank=True, verbose_name='标签')
# RAG 相关字段(预留)
embedding = models.TextField(
blank=True,
null=True,
verbose_name='文本向量 (JSON 格式)'
)
embedding_model = models.CharField(
max_length=50,
blank=True,
default='',
verbose_name='Embedding 模型版本'
)
# 时间戳
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 = ['-date', '-created_at']
indexes = [
models.Index(fields=['lobster', 'date']),
models.Index(fields=['category', 'date']),
models.Index(fields=['date']),
]
def __str__(self):
return f'{self.lobster.emoji} {self.lobster.name} - {self.date} - {self.get_category_display()}'
def get_content_preview(self, length=50):
"""获取内容预览"""
if len(self.content) <= length:
return self.content
return self.content[:length] + '...'