【问题标题】:Return hybrid property from SQLAlchemy class through JSON in Flask通过 Flask 中的 JSON 从 SQLAlchemy 类返回混合属性
【发布时间】:2021-04-02 21:33:12
【问题描述】:

在以下方面寻求帮助。

我在 Python 3+ 上使用 flask_sqlalchemy。我有一个简单的用户和培训课程;下面的定义。我在 Training 类上有一个混合属性,它将返回一个布尔值,指示用户是否订阅了培训。这在使用 Jinja 模板引擎时就像一个魅力,因为我可以使用“training.is_subscribed(current_user)”。

{% if training.is_subscribed(current_user) %}
<button type="button" class="btn btn-outline-success" disabled>Subscribed</button> You can no longer join
{% else %} 

但是,现在我也在编写 API 路由并返回 JSON。我正在使用一个简单的 Schema (marshmallow_sqlalchemy) 来序列化 Training 实例。但是,当尝试添加“已订阅”时,我遇到了错误,表明我没有传递用户。这是真的,但我不知道该怎么做。你能帮忙吗?

TypeError: is_subscribed() 缺少 1 个必需的位置参数:'user'

谢谢! 斯科特

定义

training_subscribers = db.Table('training_subscribers',
    db.Column('subscriber_id', db.Integer(), db.ForeignKey('user.id')),
    db.Column('training_id', db.Integer(), db.ForeignKey('training.id')))

class User(db.Model, UserMixin):

    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)

    trainings = db.relationship('Training', secondary=training_subscribers,
                        backref=db.backref('subscribers', lazy='dynamic'))  

class Training(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(250), nullable=False)

    @hybrid_property
    def is_subscribed(self, user) -> bool:
        return self.subscribers.filter(
            training_subscribers.c.subscriber_id == user.id).count() > 0

class TrainingSchema(SQLAlchemySchema):
    class Meta:
        model = Training
        fields = ("is_subscribed","title", "id")

获取 JSON 响应的代码

@mod_trainings.route('/json/bydate/<int:year>/<int:month>/<int:day>', methods=['GET'])
@login_required
def showUpcomingTrainingsJSONByDate(year, month, day):
    trainings = trainingController.getTrainingsAtDate(year, month, day)
    training_schema = TrainingSchema(many=True)
    return jsonify(training_schema.dump(trainings))

def getTrainingsAtDate(year, month, day):
    trainings_q = db.session.query(Training).filter(extract('year', Training.starts_at)==year).filter(extract('month', Training.starts_at)==month).filter(extract('day', Training.starts_at)==day).all()
    return trainings_q

【问题讨论】:

    标签: python flask orm flask-sqlalchemy marshmallow


    【解决方案1】:

    training.is_subscribed 实际上不是方法,而是属性,因此不可调用。太复杂了。它是如何工作的,不是调用函数而是取出函数。那么当你提到training.is_subscribed 时,你得到的是is_subscribed(self, user) 本身。因此:

    TypeError: is_subscribed() 缺少 1 个必需的位置参数:'user'

    发生了。

    好吧,我们该怎么办?它是如此容易。过滤数据直到响应 JSON。使用current_user 进行渲染意味着必须能够从flask 中获取。

    【讨论】:

    • hi Akihito - 感谢您的回复。不知道我是否遵循,你能给我举个例子吗?再次感谢,斯科特
    猜你喜欢
    • 2021-04-19
    • 2013-10-23
    • 2017-12-05
    • 2020-07-02
    • 2013-01-08
    • 1970-01-01
    • 2012-12-14
    • 2015-06-07
    • 1970-01-01
    相关资源
    最近更新 更多