数据表的关系
用户关系
这里主要实现了三个关系,用户主要有三个关系
- 用户收藏的文章
- 用户所有的分析
- 用户所发布的文章
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')