Flask-SQLAlchemy - 向查询添加新列以传递给模板

时间:2016-03-15 21:56:50

标签: python flask sqlalchemy flask-sqlalchemy

对于使用Flask-SQLAlchemy的Flask中的简单库应用程序,我有一个Book表和一个Checkout表:

class Checkout(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    checkout_date = db.Column(db.DateTime, nullable=False, default=func.now())
    return_date = db.Column(db.DateTime)

    book_id = db.Column(db.Integer, db.ForeignKey('book.id'))
    book = db.relationship('Book',
        backref=db.backref('checkout', lazy='dynamic'))

    def __repr__(self):
        return '<Checkout Book ID=%r from %s to %s>' % (self.book.id, self.checkout_date, self.return_date)

我想保留所有结帐记录,并且我认为执行此操作的规范化方法是使用Checkout.return_date来确定是否返回该书。如果任何关联的Checkout记录的返回日期为空,则仍会检出Book,如果它没有空记录,则该书“可用”。 (实际上它永远不应该有两个null return_dates)

此视图的SQL将是:

select book.*, min(checkout.return_date is not null) as available 
from book 
left join checkout 
on book.id = checkout.book_id
group by book.id;

我无法弄清楚如何在没有使用原始SQL字符串的情况下在SQLAlchemy中执行此操作:

db.session.query(Book).from_statement('select book.*, min(checkout.return_date is not null) as available from book left join checkout on book.id = checkout.book_id group by book.id').all()

但我无法访问spam_book.available:我收到错误'Book' object has no attribute 'available'

有没有办法在Book上添加动态临时属性以传递给模板?或者有更好的方法来做这件事吗?

我的最终目标是能够在模板中为每本书执行{% if book.available %}

1 个答案:

答案 0 :(得分:1)

根据您的说明,我们了解您的BookCheckout关系是OneToMany而您正在做的事情:

  • 只能为一张记录签出一本书
  • 您的图书馆可能有一本书的多个副本
  • 一本书的不同副本将具有不同且唯一的book_id

尝试为Book模型添加方法。

class Book(db.Model):
    # ...something you already have

    def is_available(self):
        return not self.checkout.filter(Checkout.return_date.isnot(None)).scalar()

在模板中,只需使用:

{% if book.is_available %}

应该这样做。

这没有经过测试,因为我手头没有SQLAlchemy。请告诉我它是否无效。