[英]Flask-SQLAlchemy - adding a new column to a query to pass to a template
For a simple library app in Flask with Flask-SQLAlchemy, I have a Book table and a Checkout table: 对于Flask中带有Flask-SQLAlchemy的简单图书馆应用,我有一个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)
I want to keep all checkout records, and I figure the normalized way to do this is to use Checkout.return_date
to determine if the book is returned or not. 我想保留所有结帐记录,并且我认为执行此操作的标准化方法是使用Checkout.return_date
来确定是否退还该书。 If the return date of any associated Checkout record is null, the Book is still checked out and if it has no null records, the book is "available". 如果任何关联的Checkout记录的返回日期为空,则该书仍被检出,如果没有空记录,则该书为“可用”。 (Really it should never have two null return_dates) (真的,它永远不能有两个null return_dates)
The SQL for this view would be: 该视图的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;
I can't figure out how to do this in SQLAlchemy without copping out and using a raw SQL string: 我无法弄清楚如何在SQLAlchemy中做到这一点,而无需弄清楚并使用原始SQL字符串:
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()
But I can't access spam_book.available
: I get the error 'Book' object has no attribute 'available'
但是我无法访问spam_book.available
:我收到错误'Book' object has no attribute 'available'
Is there a way to add a dynamic, temporary attribute on to a Book to pass to the template? 有没有一种方法可以在Book上添加动态的临时属性以传递给模板? Or is there a better way to go about doing this? 还是有更好的方法来做到这一点?
My end goal is to be able to do {% if book.available %}
for each book, in the template. 我的最终目标是能够在模板中为每本书进行{% if book.available %}
。
From your description, I understand your Book
to Checkout
relationship is OneToMany and you are doing: 根据您的描述,我了解您的Book
与Checkout
关系是OneToMany,并且您正在执行以下操作:
book_id
一本书的不同副本将具有不同且唯一的book_id
Try to add a method for your Book
model. 尝试为您的Book
模型添加方法。
class Book(db.Model):
# ...something you already have
def is_available(self):
return not self.checkout.filter(Checkout.return_date.isnot(None)).scalar()
In the template, just use: 在模板中,只需使用:
{% if book.is_available %}
should do the trick. 应该可以。
This is not tested as I don't have SQLAlchemy at hand. 这没有经过测试,因为我手头没有SQLAlchemy。 Please tell me if it does not work. 请告诉我它是否无效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.