Заявка, връщаща всяко покритие в db за всеки запис?

Заявката ми изглежда връща 1 запис за всяка корица. Тоест, ако имам 3 корици в базата данни, тогава заявката ще върне запис #1 три пъти с всяка от различните корици. Тъй като имам 7 записа, получавам 21 резултата. Как да структурирам заявката си, за да върна корицата, свързана със записа?

Ето какво имам:

@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 %}

Смяната на реда на циклите entries и cvr_entries for не променя нищо. Опитах също да добавя 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

person user2986242    schedule 09.11.2014    source източник
comment
Можете ли да публикувате своите модели SQLAlchemy? По-специално, имате ли дефинирана връзка между Book и Cover (с обратна препратка)? Ако е така, трябва да можете да премахнете изцяло cvr_entries заявката и да промените вътрешния си for цикъл, за да бъде нещо като {% for cvr in entry.covers %}.   -  person jonafato    schedule 09.11.2014
comment
В допълнение към предишния ми коментар можете да използвате joinedload за предотвратяване на ненужни заявки вътре в цикъла.   -  person jonafato    schedule 09.11.2014
comment
@jonafato Опитах cvr_entries = Cover.query.options(joinedload(Cover.book)), но получих NameError: global name 'joinedload' is not defined. Опитах и ​​подхода entry.covers, но не бяха върнати никакви записи.   -  person user2986242    schedule 09.11.2014
comment
Трябва да импортирате joinedload от sqlalchemy.orm, преди да можете да го използвате.   -  person dirn    schedule 09.11.2014
comment
Импортирах го и получих грешката InvalidRequestError: 'Cover.book' does not support object population - eager loading cannot be applied. Намерих решение тук, но това не проработи. Също така промених зареждането си от dynamic на joined без резултат.   -  person user2986242    schedule 09.11.2014


Отговори (1)


Като цяло, вие итерирате модела - вашите взаимоотношения трябва да ви позволяват да правите:

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_cover на covers, за да стане по-подобен на естествен език, когато имате достъп до модела.

person Doobeh    schedule 09.11.2014