Ошибка при разборе XML в моем шаблоне Flask (Jinja2) - PullRequest
0 голосов
/ 26 апреля 2020

При работе с Flask и отправке значений в шаблон я получаю следующее ошибка :

jinja2.exceptions.UndefinedError: 'str object' has no attribute 'best_book'

Ответ от вызова API для https://www.goodreads.com/search.xml дает мне следующее XML.

Ответ API Strtcure данных

<results>
    <work>
        <original_publication_year type="integer">1985</original_publication_year>
        <average_rating>4.30</average_rating>
        <best_book type="Book">
            <title>Ender’s Game (Ender’s Saga, #1)</title>
            <author>
                <id type="integer">589</id>
                <name>Orson Scott Card</name>
            </author>
        </best_book>
    </work>
</results>

Код моего Python кода внутри приложения Flask, где ответ анализируется в application.py

works = (xmltodict.parse(response.content, process_namespaces=True)
                     ["GoodreadsResponse"]["search"]["results"])
return render_template("results.html", works=works)

результаты. html

{% for work in works %}
<div>
    <p>
        <span>{{work.best_book.title}}</span> -
        <span>{{work.original_publication_year}}</span>
    </p>
    <p>{{work.average_rating}} </p>
    <p>{{work.author.name}} </p>
</div>
{% endfor %}

Возвращает Ошибка

jinja2.exceptions.UndefinedError: 'str object' has no attribute 'best_book'

1 Ответ

0 голосов
/ 26 апреля 2020

Существует проблема согласованности, когда вы анализируете файл только с одним результатом. Вы можете исправить это следующим образом (также обратите внимание на ["work"]):

works = (xmltodict.parse(test, process_namespaces=True)["results"]["work"])
# here we have to trick to make sure we have a list even when there is only one result
if type(works) != list:
    works = [works]
return render_template("results.html", works=works)

и в шаблоне work это диктат, поэтому:

{% for work in works %}
<div>
    <p>
        <span>{{work['best_book']['title']}}</span> -
    </p>
    <p>{{work['average_rating']}} </p>
</div>
{% endfor %}
...