Displaying database information in HTML using Flask, Jinja2, Python and SQLAlchemy

Question:

I’m trying to display information that I tried inserting into a model on my Flask HTML site. I can’t figure out how to do this because the code doesn’t seem to display anything on the page.
Here’s my model:

class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(150))
    authors_name = db.Column(db.String(150))
    publisher = db.Column(db.String(150))
    page_count = db.Column(db.Integer)
    publish_year = db.Column(db.Date)
    image = db.Column(db.String(150))

Code in my views.py file:

views = Blueprint('views', __name__, template_folder="templates")

@views.route('/')
@login_required
def home():
    return render_template("home.html")

@views.route('/books', methods=['GET','POST'])
@login_required
def books():
    if request.method == 'GET':
        new_book = Book(id=1, title='Moby-Dick, or The Whale', authors_name='Herman Melville', publisher='Harper & Brothers', page_count=378, publish_year=1851, image='<img src="/static/images/{{ mobydick.jpg }}">')
        db.session.add(new_book)
        db.session.commit()
    books = Book.query.all()
    return render_template("books.html", books=books)

Here’s my books.html file:

{% extends "base.html" %} {% block title %}Books{% endblock %}
{% block content %}
<h1>Books!</h1>
<ul>
    {% for book in books %}
    <li>{{ book.title }}</li>
    {% endfor %}
</ul>
{% endblock %}

I want to display all of the information including the image, I’m not too sure how to do do that either. For now I’m trying to display the title only, but here’s what I’m getting:
It's supposed to say 'Moby-Dick, or The Whale'

I’m new to databases and I don’t know how to work with them, please help. If there are any other issues with my code let me know

Asked By: rupertpurple

||

Answers:

You probably have to pass the books to the template like:

    return render_template("books.html", books=books)

Also make sure you always set books for both POST and GET. I can’t tell if the code just got formatted wrong or not but it looks to be only set for POST.

@views.route('/books', methods=['GET','POST'])
@login_required
def books():
    if request.method == 'POST':
        new_book = Book(id=1, title='Moby-Dick, or The Whale', authors_name='Herman Melville', publisher='Harper & Brothers', page_count=378, publish_year=1851, image='<img src="/static/images/{{ mobydick.jpg }}">')
        db.session.add(new_book)
        db.session.commit()
    # Always get these for GET or POST.
    books = Book.objects.all()
    # Make sure to pass them to template.
    return render_template("books.html", books=books)
Answered By: Ian Wilson

Turns out I was inserting the wrong kind of information into the publish_year column, I changed the Book table to look like this:

class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(150))
    authors_name = db.Column(db.String(150))
    genre = db.Column(db.String(150))
    publish_year = db.Column(db.String(150))
    publisher = db.Column(db.String(150))
    page_count = db.Column(db.Integer)
    image = db.Column(db.String(150))

Here’s how I insert information into the table:

@views.route('/books', methods=['GET','POST'])
@login_required
def books():
    if request.method == 'GET':
        new_book = Book(id=1, title='Moby-Dick, or The Whale', authors_name='Herman Melville', genre='Adventure Novel, Epic', publish_year='1851', publisher='Harper & Brothers', page_count=378, image='mobydick.jpg')
        db.session.add(new_book)
        db.session.commit()
    books = Book.query.all()
    return render_template("books.html", books=books)

I was able to display information from the database after fixing it this way

Answered By: rupertpurple
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.