Flask Framework Cookbook(Second Edition)
上QQ阅读APP看书,第一时间看更新

How to do it...

First, manually create a database in MongoDB using the command line. Let's name this database my_catalog:

>>> mongo
MongoDB shell version: v4.0.4
> use my_catalog
switched to db my_catalog

The following is an application that is a rewrite of our catalog application using MongoDB.

The first change comes to our configuration file, my_app/__init__.py:

from flask import Flask 
from flask_mongoengine import MongoEngine 
from redis import Redis 
 
 
app = Flask(__name__) 
app.config['MONGODB_SETTINGS'] = {'DB': 'my_catalog'} 
app.debug = True 
db = MongoEngine(app) 
 
redis = Redis() 
 
from my_app.catalog.views import catalog 
app.register_blueprint(catalog) 
Note that instead of the usual SQLAlchemy-centric settings, we now have MONGODB_SETTINGS. Here, we just specify the name of the database to use, which, in our case, is my_catalog.

Next, we will create a Product model using MongoDB fields. This happens as usual in the models file, flask_catalog/my_app/catalog/models.py:

import datetime 
from my_app import db 
 
 
class Product(db.Document): 
    created_at = db.DateTimeField( 
        default=datetime.datetime.now, required=True 
    ) 
    key = db.StringField(max_length=255, required=True) 
    name = db.StringField(max_length=255, required=True) 
    price = db.DecimalField() 
 
    def __repr__(self): 
        return '<Product %r>' % self.id 
Now would be a good time to look at the MongoDB fields used to create the model above, and their similarity with the SQLAlchemy fields used in the previous recipes. Here, instead of an ID field, we have created_at, which stores the timestamp in which the record was created. Also note the class that is inherited by Product while creating the model. In case of SQLAlchemy, it is db.Model and, in the case of MongoDB, it is db.Document. This is in accordance with how these database systems work. SQLAlchemy works with conventional RDBMS, but MongoDB is a NoSQL document database system.

The following is the views file, namely, flask_catalog/my_app/catalog/views.py:

from decimal import Decimal 
from flask import request, Blueprint, jsonify 
from my_app.catalog.models import Product 
 
catalog = Blueprint('catalog', __name__) 
 
@catalog.route('/') 
@catalog.route('/home') 
def home(): 
    return "Welcome to the Catalog Home." 
 
@catalog.route('/product/<key>') 
def product(key): 
    product = Product.objects.get_or_404(key=key) 
    return 'Product - %s, $%s' % (product.name, product.price) 
 
@catalog.route('/products') 
def products(): 
    products = Product.objects.all() 
    res = {} 
    for product in products: 
        res[product.key] = { 
            'name': product.name, 
            'price': str(product.price), 
        } 
    return jsonify(res) 
 
@catalog.route('/product-create', methods=['POST',]) 
def create_product(): 
    name = request.form.get('name') 
    key = request.form.get('key') 
    price = request.form.get('price') 
    product = Product( 
        name=name, 
        key=key, 
        price=Decimal(price) 
    ) 
    product.save() 
    return 'Product created.' 

You will notice that it is very similar to the views created for the SQLAlchemy-based models. There are just a few differences in the methods that are called from the MongoEngine extension, and these should be easy to understand.