Files
diary-news/backend/app/models/article_read.py
xiaji 4ca05b8b7d fix: 修两个 bug
1. ArticleRead.user_id 改 Integer(users.id 是 Integer,不是 BigInteger)
   alembic 0007 同样改 Integer
2. ArticleDetail.vue toggleRead 重复 catch 块导致 build 失败
   (edit 时新加的 catch 跟 toggleStar 残留的 catch 撞了)
2026-06-13 21:10:22 +08:00

48 lines
1.5 KiB
Python

"""文章已读记录(per-user)。
设计:
- 复合主键 (user_id, article_id) — 天然防重复,标记已读是幂等的
- read_at 默认 now(),用于排序(最近已读在前)
- 索引: (user_id, read_at DESC) — 用户查自己最近已读用
(article_id) — 反向查"谁读过这文章"(暂不用,留扩展)
注意:
- 删文章时 ondelete=CASCADE 自动清掉已读记录
- 这是和 bookmarks 并列的"用户行为"
- user_id 是 Integer(users.id 是 Integer),article_id 是 BigInteger(articles.id 是 BigInteger)
"""
from __future__ import annotations
from datetime import datetime
from sqlalchemy import BigInteger, DateTime, ForeignKey, Index, Integer, func
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base
class ArticleRead(Base):
__tablename__ = "article_reads"
user_id: Mapped[int] = mapped_column(
Integer, ForeignKey("users.id", ondelete="CASCADE"), primary_key=True
)
article_id: Mapped[int] = mapped_column(
BigInteger,
ForeignKey("articles.id", ondelete="CASCADE"),
primary_key=True,
)
read_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
server_default=func.now(),
nullable=False,
)
__table_args__ = (
Index("ix_article_reads_user_read_at", "user_id", "read_at"),
Index("ix_article_reads_article", "article_id"),
)
def __repr__(self) -> str:
return f"<ArticleRead user={self.user_id} article={self.article_id} at={self.read_at}>"