Skip to content

数据表的关系

用户关系

这里主要实现了三个关系,用户主要有三个关系

  • 用户收藏的文章
  • 用户所有的分析
  • 用户所发布的文章
python
from sqlalchemy.orm import backref, relationship 

class UserORM(BaseORM):
    """用户"""
    __tablename__ = "forum_user"

    # ...

    """关系部分"""
    # 当前用户收藏的所有文章
    collection_articles = relationship(
        "ArticleORM", secondary=tb_user_collection, lazy="dynamic"
    )
    # 用户所有的粉丝,添加了反向引用 followed ,代表用户都关注了哪些人
    followers = relationship(
        "UserORM",
        secondary=tb_user_follows,
        primaryjoin=id == tb_user_follows.c.followed_id,
        secondaryjoin=id == tb_user_follows.c.follower_id,
        backref=backref("followed", lazy="dynamic"),
        lazy="dynamic",
    )
    # 当前用户所发布的文章
    article_list = relationship("ArticleORM", backref="user", lazy="dynamic")

    # 当前用户发表的评论
    comment_list = relationship("CommentORM", backref="user", lazy="dynamic")

    # 当前用户点赞过那些评论
    comment_like_list = relationship("CommentLikeORM", backref="user", lazy="dynamic")

文章与评论关系

每篇文章都可以包含多个评论,文章和评论之间是一对多的关系:

python
class ArticleORM(BaseORM):
    """文章"""
    __tablename__ = "forum_article"

    # ...

    """关系部分"""
    # 收藏文章的用户
    user_list = relationship(
        "UserORM", secondary="forum_user_collections", lazy="dynamic"
    )

    # 当前新闻的所有评论
    comment_list = relationship("CommentORM", lazy="dynamic")

评论与评论

博客程序中的评论要⽀持存储回复。想要为评论添加回复,并在获取某个评论时可以通过关系属性获得相对应的回复,这样就可以在模板中显示出评论之间的对应关系。

下面是更新后的 Comment 模型:

python
class CommentORM(BaseORM):
    """评论"""
    __tablename__ = "forum_comment"

    # ...

    """关系部分"""
    parent = relationship("CommentORM", remote_side=[id])

    # 当前用户点赞过那些评论
    comment_like_list = relationship('CommentLikeORM', backref='comment', lazy='dynamic')

在 Comment 模型中,有一个 parent_id 字段,通过 sa.ForeignKey() 设置一个外键指向自⾝的 id 字段:

python
parent_id = sa.Column(
    sa.Integer,
    sa.ForeignKey("forum_comment.id"),
    comment="父评论id"
)

关系两侧的关系属性都在 Comment 模型中定义,需要特别说明的是表示被回复评论(父对象)的标量关系属性 replied 的定义。

分类与文章的关系

在分类和文章之间需要建立一对多关系。我们为 Post 模型添加了一个 category_id 外键字段,作为指向分类模型的外键,存储分类记录的主键值,同时在 Post 类中创建标量关系属性 category,在 Category 类中创建集合关系属性 article_list,如下所示:

python
class CategoryORM(BaseORM):
    """文章分类"""
    __tablename__ = "forum_category"

    # ...

    """关系部分"""
    article_list = relationship('ArticleORM', backref='category', lazy='dynamic')