Flask-SQLAlchemy多对多序列化统计帖子奖项数量 传参报错求助
错误原因
- 你给
serialize_awards加了@property装饰器,被该装饰器修饰的方法会被视为属性访问,不支持传入额外参数,你调用self.serialize_awards(post=self)的写法本身不符合property的使用规则 serialize_awards是Post类的实例方法,当前实例self本身就是你要传的post对象,完全不需要额外定义post参数传入- Award_Type类的
serialize属性中直接调用self.count(post),这里的post变量没有上下文定义,无法被识别
修复后的代码
class Post(SearchableMixin, db.Model): id=db.Column(db.Integer, primary_key=True) title = db.Column(db.String(300)) @property def serialize(self): return { 'id' : self.id, 'title' : self.title, 'awards' : self.serialize_awards } @property def serialize_awards(self): # 直接把当前post实例self传给奖项的序列化方法 return [award.get_serialize(post=self) for award in self.award_types()] def award_types(self): return Award_Type.query.order_by(Award_Type.cost.desc()).all() class Award_Type(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False) # 若你原表已定义cost字段可删除该行,否则要补充该字段否则排序逻辑会报错 cost = db.Column(db.Integer, nullable=False, default=0) # 把property装饰器去掉,改为接收post参数的普通序列化方法 def get_serialize(self, post): return { 'name' : self.name, 'count': self.count(post) } def count(self, post): return Award.query.filter_by(award_id=self.id, post_id=post.id).count()
可选性能优化
如果数据量较大,可以避免循环调用count查询产生N+1性能问题,在Post类中一次性统计所有奖项的计数:
@property def serialize_awards(self): from sqlalchemy import func award_counts = db.session.query( Award_Type.id, Award_Type.name, func.count(Award.id).label('count') ).outerjoin(Award, (Award.award_id == Award_Type.id) & (Award.post_id == self.id) ).group_by(Award_Type.id).order_by(Award_Type.cost.desc()).all() return [{"name": ac.name, "count": ac.count} for ac in award_counts]
内容的提问来源于stack exchange,提问作者rockets4all
相关产品推荐
相关产品推荐

