因此,我试图向我的代码中添加一个喜欢按钮的功能,该功能允许用户喜欢特定帖子。点赞次数将链接到已登录的用户,并显示点赞次数。实施前端并不困难,但是后端存在问题。
我是using this post here as a guide which does a follower system instead
这是我到目前为止所拥有的?
我在models.py中为喜欢创建了一个表:
likers = db.Table('likers',
db.Column('liker_id', db.Integer, db.ForeignKey('post.id')),
db.Column('liked_id', db.Integer, db.ForeignKey('post.id'))
)
在我的用户类的Models.py中:
class User(db.Model, UserMixin):
#Code
liked = db.relationship(
'User', secondary=likers,
primaryjoin=(likers.c.liker_id == id),
secondaryjoin=(likers.c.liked_id == id),
backref = db.backref('likers', lazy='dynamic'), lazy='dynamic')
def like(self, post):
if not self.is_liking(post):
self.liked.append(post)
def unlike(self, post):
if self.is_liking(post):
self.liked.remove(post)
def is_liking(self, post):
return self.liked.filter(
likers.c.liked_id == post.id).count() > 0
在routes.py中-对于我的用户蓝图,我有:
@users.route("/like/<int:post_id>")
@login_required
def like(post_id):
post = Post.query.get_or_404(post_id)
current_user.like(post)
db.session.commit()
flash('Post has been liked')
return redirect(url_for('posts.post', post_id=post.id))
@users.route("/unlike/<int:post_id>")
@login_required
def unlike(post_id):
post = Post.query.get_or_404(post_id)
current_user.unlike(post)
db.session.commit()
flash('Post has been unliked')
return redirect(url_for('posts.post', post_id=post.id))
我在做什么错?我不断收到诸如以下错误:
builtins.KeyError
KeyError: 'likers'
我已经完成了一个评论部分,并且我知道喜欢的人的关系将类似于评论,但是我正在努力实现它。我对Flask还是比较陌生,我曾尝试使用这些文档,但找不到任何可帮助我的东西...
这是我最后的希望。
答案 0 :(得分:2)
class User(UserMixin, db.Model):
# Code
liked = db.relationship(
'PostLike',
foreign_keys='PostLike.user_id',
backref='user', lazy='dynamic')
def like_post(self, post):
if not self.has_liked_post(post):
like = PostLike(user_id=self.id, post_id=post.id)
db.session.add(like)
def unlike_post(self, post):
if self.has_liked_post(post):
PostLike.query.filter_by(
user_id=self.id,
post_id=post.id).delete()
def has_liked_post(self, post):
return PostLike.query.filter(
PostLike.user_id == self.id,
PostLike.post_id == post.id).count() > 0
class PostLike(db.Model):
__tablename__ = 'post_like'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
post_id = db.Column(db.Integer, db.ForeignKey('post.id'))
@app.route('/like/<int:post_id>/<action>')
@login_required
def like_action(post_id, action):
post = Post.query.filter_by(id=post_id).first_or_404()
if action == 'like':
current_user.like_post(post)
db.session.commit()
if action == 'unlike':
current_user.unlike_post(post)
db.session.commit()
return redirect(request.referrer)
然后,当您列出自己的帖子时,设置锚点如下:
{% for post in posts %}
{% if current_user.has_liked_post(post) %}
<a href="{{ url_for('like_action', post_id=post.id, action='unlike') }}">Unlike</a>
{% else %}
<a href="{{ url_for('like_action', post_id=post.id, action='like') }}">Like</a>
{% endif %}
{% endfor %}
假设您的Post
模型看起来像这样:
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.Text)
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
recipient_id = db.Column(db.Integer, db.ForeignKey('user.id'))
likes = db.relationship('PostLike', backref='post', lazy='dynamic')
您将使用:
p = Post.query.filter_by(id=1).first()
p.likes.count()
或者,您可以在.html文件中使用它:
{% for post in posts %}
{% if current_user.has_liked_post(post) %}
<a href="{{ url_for('like_action', post_id=post.id, action='unlike') }}">Unlike</a>
{% else %}
<a href="{{ url_for('like_action', post_id=post.id, action='like') }}">Like</a>
{% endif %}
{{ post.likes.count() }} likes
{% endfor %}
答案 1 :(得分:0)
您的错误表明用户实例没有正确定义的likers
关系。
我怀疑这里有几个错误:
likers
表应该具有指向liker_id
的外键,指向用户表,而不是帖子。您在liked
模型中的User
关系应该是与Post
模型(以likers
表为辅助关系)的关系,而不是与自身的关系(即User
模型)。
尝试以下这种关系:
liked = db.relationship(
'Post', secondary="likers",
primaryjoin="likers.liker_id == users.id",
secondaryjoin="likers.liked_id == posts.id",
backref=db.backref('likers', lazy='dynamic'), lazy='dynamic')
您的is_liking()
方法似乎很奇怪。我会这样写:
(如果不希望每个用户收到很多喜欢的帖子)return post in self.liked
(如果期望每个用户有很多喜欢的帖子)return db.session.execute("SELECT COUNT(*) FROM likers WHERE liked_id = :post_id AND liker_id = :user_id", {'user_id': self.id, 'post_id': post.id}).fetchone()[0] > 0
(无关,可能不正确),您的User模型从db.Model
和UserMixin
继承的顺序很重要,当前,您的UserMixin仅用于db.Model中找不到的方法。并且不会覆盖任何内容(也许就是您想要的)。参考:Python的Method Resolution Order(MRO)
答案 2 :(得分:0)
以上代码有效,但是由于“ current_user”而注销了用户制造商错误。所以我们的html文件必须是这样的
{% for post in posts %}
{% if current_user.is_authenticated %}
{% if current_user.has_liked_post(post) %}
<a href="{{ url_for('like_action', post_id=post.id, action='unlike') }}">Unlike</a>
{% else %}
<a href="{{ url_for('like_action', post_id=post.id, action='like') }}">Like</a>
{% endif %}
{{ post.likes.count() }} likes
{% else %}
{{ post.likes.count() }} likes
{% endif %}{% endfor %}