This video is available to students only

Building pages using our models

Building pages using our models

Now that we have the ability to retrieve stored products from our database within the console, we can use SQLAlchemy to render pages that display the data for products we have.

The two routes that we will need to implement to build out our (read only) product catalog is one to list all of the products and one to display the product details.

Setting up a blueprint

As we saw earlier, blueprints are a useful organizational tool in Flask applications to split up your routes. A common pattern is to organize blueprints by the models they work with.

How large should blueprints be? As always, it varies. As a rule of thumb, if your blueprint only contains a single route, you may have gone too granular. If your blueprint is defining over ten routes, it may be too large and could benefit from splitting it up. A common way to organize blueprints is by the URL path and/or model they work with. If you blueprint is pushing 250+ lines of code, you may benefit from some additional modularization.

Here we can create a blueprint for our product catalog called products.py. To do that, we'll need to create a blueprints folder in the yumroad folder. Then inside of the blueprints folder, create a file called products.py where our blueprint and routes will be defined.

At this point, your folder structure should like this:

yumroad/
    blueprints/
        products.py
    __init__.py
    config.py
    models.py
requirements.txt
conftest.py

Now within products.py, we'll set up the basics of a blueprint called products just like we did in Chapter 3.

from flask import Blueprint, render_template

products = Blueprint('products', __name__)

@products.route('/')
def index():
    return "All Products: Coming soon"

Recall: The first argument of the Blueprint initialization is the name that will used when trying to get the route path when using url_for. In this case it will be products

Now we need to import and register the blueprint within our create_app function (in yumroad/__init__.py). While we are at it, we can also prefix the URL of all the routes in this blueprint with /products to start building up the (conceptual) routing layout for our application.

yumroad-app/yumroad/\_\_init\_\_.py
from flask import Flask, render_template

from yumroad.blueprints.products import products
from yumroad.config import configurations
from yumroad.extensions import (db)


def create_app(environment_name='dev'):
    app = Flask(__name__)
    app.config.from_object(configurations[environment_name])
    db.init_app(app)
    app.register_blueprint(products, url_prefix="/product")
    return app

# FLASK_DEBUG=true FLASK_APP="yumroad:create_app" flask run

At this point, we can now run the application using the flask run command. In our terminal, within the top level folder (that contains yumroad and requirements.txt), run the following command to set up our server FLASK_ENV=development FLASK_APP="yumroad:create_app" flask run.

Reminder: You can export the environment variables into your terminal session to only have to type flask run or you can create a script to launch your development environment.

export FLASK_ENV=development
export FLASK_APP=yumroad:create_app
# Now you can just run the following command in your terminal
flask run

Setting up Jinja templates

In chapter 3, we talked about how to organize templates with blueprints. Since this is a new application, we'll have to set up that structure again, starting with a base_layout.html file.

Within our yumroad folder, create a folder called templates and create a base_layout.html file within it.

This file will define the outlines of a basic HTML page (using Bootstrap for basic styling) with two blocks for templates that use this base to customize the content and page title.

yumroad-app/yumroad/templates/base_layout.html
<!DOCTYPE html>
<html>
    <head>
        <title>
            {% block title %}{% endblock %} Yumroad
        </title>

        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous">
    </head>
    <body>
        <nav class="navbar navbar-light bg-light justify-content-between">
            <a class="navbar-brand">Yumroad</a>
        </nav>

        <div class="container mt-3">
           {% block content %}{% endblock %}
       </div>
    </body>
</html>
Please select a discussion on the left.