2014-11-09 79 views
0

我的查詢似乎每個封面都返回1個條目。也就是說,如果我在數據庫中有3個封面,那麼查詢將返回每個不同封面三次的條目#1。由於我有7個條目,我得到了21個結果。我如何構建查詢以返回與條目相關聯的封面?查詢以db爲單位返回每個條目的每個封面?

這是我有:

@app.route('/list', methods=['GET', 'POST']) 
def list(): 
    entries = Book.query.order_by(Book.id.desc()).all() 
    cvr_entries = Cover.query.filter(Cover.book).all() 

    ### Other queries I've tried ### 

    # cvr_entries = Cover.query.join(Cover.book).all() 
    # cvr_entries = Cover.query.filter(Cover.book.any()) 
    # cvr_entries = Cover.query.filter(Cover.book.any()).all() 

    return render_template(
     'list.html', 
     entries=entries, 
     cvr_entries=cvr_entries) 

下面是/list輸出頁面:

{% for entry in entries %} 
{% for cvr in cvr_entries %} 

<article class="entry"> 
    <img src="/static/data/covers/{{ cvr.name }}" alt="Cover for {{ entry.title }}" /> 
    <ul class="entry-info"> 
     <li class=""><h2>{{ entry.title }}</h2></li> 
     <li class="">Summary: {{ entry.summary|truncate(30, true) }}</li> 
    </ul> 
</article> 

{% endfor %} 
{% endfor %} 

切換entriescvr_entriesfor循環的順序改變不了什麼。我也嘗試添加first()代替all(),但它說:

TypeError: 'Cover' object is not iterable 

所以這是一個半身像,導致一個錯誤。我不明白如何構建查詢。

這裏是我的模型,通過@jonafato的要求:

book_to_cover = db.Table('book_to_cover', 
    db.Column('cover_id', db.Integer, db.ForeignKey('cover.id')), 
    db.Column('book_id', db.Integer, db.ForeignKey('book.id')) 
) 

class Book(db.Model): 
    __tablename__ = 'book' 

    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String()) 
    summary = db.Column(db.Text) 

    book_to_cover = db.relationship('Cover', secondary=book_to_cover, 
     backref=db.backref('book', lazy='dynamic')) 

    def __repr__(self): 
     return "<Book (title='%s')>" % (self.title) 


class Cover(db.Model): 
    __tablename__ = 'cover' 

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String()) 

    def __repr__(self): 
     return "<Cover (name='%s')>" % self.name 
+0

你可以發佈你的SQLAlchemy模型嗎?特別是,你是否在'Book'和'Cover'之間定義了一個關係(帶有backref)?如果是這樣,你應該能夠完全刪除'cvr_entries'查詢,並將你的''for''循環改成類似'{%for cvr in entry.covers%}''。 – jonafato 2014-11-09 07:35:58

+0

除了我之前的評論,您還可以使用['joinedload'](http://docs.sqlalchemy.org/en/rel_0_9/orm/tutorial.html#joined-load)來防止循環內部不必要的查詢。 – jonafato 2014-11-09 07:53:35

+0

@jonafato我試過'cvr_entries = Cover.query.options(joinedload(Cover.book))',但我得到了'NameError:全局名''joinedload'沒有定義。我也嘗試過'entry.covers'方法,但是根本沒有返回任何條目。 – user2986242 2014-11-09 08:11:00

回答

2

一般來說,你遍歷型號 - 你的人際關係應該允許你這樣做:

books = Book.query.all() 
return render_template('list.html', books=books) 

然後在你的Jinja2 list.html模板:

{% for book in books %} 
    <h3>{{ book }}</h3> 
    <ul> 
    {% for cover in book.book_to_cover %} 
     <li>{{ cover }}</li> 
    {% endfor %} 
    </ul> 
{% endfor %} 

它會更自然地重新命名book_to_covercovers,以便在訪問模型時更像自然語言。

相關問題