Creating a basic product model

In this recipe, we will create an application that will help us store products to be displayed on the catalog section of a website. It should be possible to add products to the catalog and delete them as and when required. As we saw in previous chapters, this is possible to do using non-persistent storage as well. But, here we will store data in a database to have persistent storage.

How to do it…

The new directory layout will look as follows:

flask_catalog/
    - run.py
    my_app/
        – __init__.py
        catalog/
            - __init__.py
            - views.py
            - models.py

First of all, we will start by modifying our application configuration file, that is, flask_catalog/my_app/__init__.py:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)

from my_app.catalog.views import catalog
app.register_blueprint(catalog)

db.create_all()

The last statement in the file is db.create_all(), which tells the application to create all the tables in the database specified. So, as soon as the application runs, all the tables will be created if they are not already there. Now is the time to create models that are placed in flask_catalog/my_app/catalog/models.py:

from my_app import db

class Product(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))
    price = db.Column(db.Float)

    def __init__(self, name, price):
        self.name = name
        self.price = price

    def __repr__(self):
        return '<Product %d>' % self.id

In this file, we have created a model named Product that has three fields, namely id, name, and price. The id field is a self-generated field in the database that will store the ID of the record and is the primary key. name is a field of type string and price is of type float.

Now, we add a new file for views, which is flask_catalog/my_app/catalog/views.py. In this file, we have multiple view methods that control how we deal with the product model and the web application in general:

from flask import request, jsonify, Blueprint
from my_app import app, db
from my_app.catalog.models import Product

catalog = Blueprint('catalog', __name__)

@catalog.route('/')
@catalog.route('/home')
def home():
    return "Welcome to the Catalog Home."

This method handles how the home page or the application landing page looks or responds to the users. You would most probably use a template for rendering this in your applications. We will cover this a bit later. Have a look at the following code:

@catalog.route('/product/<id>')
def product(id):
    product = Product.query.get_or_404(id)
    return 'Product - %s, $%s' % (product.name, product.price)

This method controls the output to be shown when a user looks up a specific product using its ID. We filter for the product using the ID and then return its information if the product is found; if not, we abort with a 404 error. Consider the following code:

@catalog.route('/products')
def products():
    products = Product.query.all()
    res = {}
    for product in products:
        res[product.id] = {
            'name': product.name,
            'price': str(product.price)
        }
    return jsonify(res)

This method returns the list of all products in the database in JSON format. Consider the following code:

@catalog.route('/product-create', methods=['POST',])
def create_product():
    name = request.form.get('name')
    price = request.form.get('price')
    product = Product(name, price)
    db.session.add(product)
    db.session.commit()
    return 'Product created.'

This method controls the creation of a product in the database. We first get the information from a request and then create a Product instance from this information. Then, we add this Product instance to the database session and finally commit to save the record to the database.

How it works…

In the beginning, the database is empty and has no product. This can be confirmed by opening http://127.0.0.1:5000/products in a browser. This would result in an empty page with just {}.

Now, first we would want to create a product. For this, we need to send a POST request, which can be sent from the Python prompt using the requests library easily:

>>> import requests
>>> requests.post('http://127.0.0.1:5000/product-create', data={'name': 'iPhone 5S', 'price': '549.0'})

To confirm whether the product is in the database now, we can open http://127.0.0.1:5000/products in the browser again. This time, it would show a JSON dump of the product details.

See also

  • The next recipe, Creating a relational category model, demonstrates the relational aspect of tables