文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
数据库模型的实现
首先,让我们在数据库中添加粉丝机制吧。这是 followers
关联表:
followers = db.Table('followers',
db.Column('follower_id', db.Integer, db.ForeignKey('user.id')),
db.Column('followed_id', db.Integer, db.ForeignKey('user.id'))
)
这是上图中关联表的直接翻译。 请注意,我没有像我为用户和用户动态所做的那样,将表声明为模型。 因为这是一个除了外键没有其他数据的辅助表,所以我创建它的时候没有关联到模型类。
现在我可以在用户表中声明多对多的关系了:
class User(UserMixin, db.Model):
# ...
followed = db.relationship(
'User', secondary=followers,
primaryjoin=(followers.c.follower_id == id),
secondaryjoin=(followers.c.followed_id == id),
backref=db.backref('followers', lazy='dynamic'), lazy='dynamic')
建立关系的过程实属不易。 就像我为 post
一对多关系所做的那样,我使用 db.relationship
函数来定义模型类中的关系。 这种关系将 User
实例关联到其他 User
实例,所以按照惯例,对于通过这种关系关联的一对用户来说,左侧用户关注右侧用户。 我在左侧的用户中定义了 followed
的关系,因为当我从左侧查询这个关系时,我将得到已关注的用户列表(即右侧的列表)。 让我们逐个检查这个 db.relationship()
所有的参数:
'User'
是关系当中的右侧实体(将左侧实体看成是上级类)。由于这是自引用关系,所以我不得不在两侧都使用同一个实体。secondary
指定了用于该关系的关联表,就是使用我在上面定义的followers
。primaryjoin
指明了通过关系表关联到左侧实体(关注者)的条件 。关系中的左侧的 join 条件是关系表中的follower_id
字段与这个关注者的用户 ID 匹配。followers.c.follower_id
表达式引用了该关系表中的follower_id
列。secondaryjoin
指明了通过关系表关联到右侧实体(被关注者)的条件 。 这个条件与primaryjoin
类似,唯一的区别在于,现在我使用关系表的字段的是followed_id
了。backref
定义了右侧实体如何访问该关系。在左侧,关系被命名为followed
,所以在右侧我将使用followers
来表示所有左侧用户的列表,即粉丝列表。附加的lazy
参数表示这个查询的执行模式,设置为动态模式的查询不会立即执行,直到被调用,这也是我设置用户动态一对多的关系的方式。lazy
和backref
中的lazy
类似,只不过当前的这个是应用于左侧实体,backref
中的是应用于右侧实体。
如果理解起来比较困难,你也不必过于担心。我待会儿就会向你展示如何利用这些关系来执行查询,一切就会变得清晰明了。
数据库的变更,需要记录到一个新的数据库迁移中:
(venv) $ flask db migrate -m "followers"
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'followers'
Generating /home/miguel/microblog/migrations/versions/ae346256b650_followers.py ... done
(venv) $ flask db upgrade
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade 37f06a334dbf -> ae346256b650, followers
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论