对于使用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 %}
。
答案 0 :(得分:1)
根据您的说明,我们了解您的Book
到Checkout
关系是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。请告诉我它是否无效。