我正在尝试检索最高得分线程启动消息的排序列表。分数的计数应该只是喜欢 - 不喜欢消息。
目前无法正常工作,尽管消息有多少喜欢和不喜欢,但得分总是为0。错误可能在下面的“运行代码”部分,因为其余部分似乎有效,但我不完全确定。
用户只能喜欢或不喜欢消息,所以我为用户和消息之间的喜欢和不喜欢做了两个单独的关系。因此,我可以很容易地跟踪用户所做的操作,并且我能够向用户显示它在UI中采取的操作。
感觉不够深入,我不知道我的方法是否是最好的方法,希望你可以帮助我走上正确的道路并帮助那些制造喜欢/不喜欢系统的人。感谢我得到的所有帮助!
表格:
like_table = db.Table('like', db.metadata,
db.Column('user', db.Integer, db.ForeignKey('user.id')),
db.Column('message', db.Integer, db.ForeignKey('message.id')))
dislike_table = db.Table('dislike', db.metadata,
db.Column('user', db.Integer, db.ForeignKey('user.id')),
db.Column('message', db.Integer, db.ForeignKey('message.id')))
用户类:
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True)
password = db.Column(db.String(255))
reg_date = db.Column(db.DateTime)
likes = db.relationship('Message', secondary=like_table, back_populates = 'likers')
dislikes = db.relationship('Message', secondary=dislike_table, back_populates = 'dislikers')
def __init__(self, uname, password):
self.username = uname
self.password = generate_password_hash(password)
self.reg_date = datetime.utcnow()
Message类:
class Message(db.Model):
__tablename__ = 'message'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(500))
post_date = db.Column(db.DateTime)
writer = db.Column(db.String(128))
writer_id = db.Column(db.Integer)
thread_start = db.Column(db.Boolean) # if it's the start of a thread
likers = db.relationship('User', secondary=like_table, back_populates = 'likes')
dislikers = db.relationship('User', secondary=dislike_table, back_populates = 'dislikes')
def __init__(self, text, writer, thread_start):
self.text = text
self.post_date = datetime.utcnow()
self.writer = writer.username
self.writer_id = writer.id
self.thread_start = thread_start
@hybrid_property
def score(self):
return func.count(Message.likers) - func.count(Message.dislikers)
要运行的代码(这里可能有问题):
top_voted_threads = db.session.query(Message, Message.score.label('total')).\
filter(Message.thread_start == True).\
join(Message.likers, aliased = True).join(Message.dislikers).\
group_by(Message).order_by('total DESC')[0:10]
print(top_voted_threads)
当前输出,分数错误地为0:
[(<app.Message object at 0x103f42278>, 0), (<app.Message object at 0x103f42e48>, 0), (<app.Message object at 0x103f688d0>, 0), (<app.Message object at 0x103f68588>, 0)]
答案 0 :(得分:0)
您没有正确使用@hybrid_attribute
。将您的score
拆分为like_score
和dislike_score
以查看疯狂的数字,因为您拥有的func.count(...)
基本上会生成不相关的查询。
下面应该会了解如何使用混合物来实现您的目的:
class Message(Base):
...
@hybrid_property
def num_likers(self):
return len(self.likers)
@num_likers.expression
def _num_likes_expression(cls):
return (
select([func.count('*').label("num_likes_value")])
.where(like_table.c.message == cls.id)
.label("num_likers")
)
@hybrid_property
def num_dislikers(self):
return len(self.dislikers)
@num_dislikers.expression
def _num_dislikes_expression(cls):
return (
select([func.count('*').label("num_dislikes_value")])
.where(dislike_table.c.message == cls.id)
.label("num_dislikers")
)
@hybrid_property
def score(self):
return self.num_likers - self.num_dislikers