開発者ドキュメント

FlaskアプリケーションでMongoDBを使用する方法

序章

Webアプリケーションでは、通常、データの組織化されたコレクションであるデータベースが必要です。 データベースを使用して、効率的に取得および操作できる永続データを保存および維持します。 たとえば、ソーシャルメディアアプリケーションでは、ユーザーデータ(個人情報、投稿、コメント、フォロワー)が効率的に操作できる方法で保存されているデータベースがあります。 さまざまな要件や条件に応じて、データベースにデータを追加、取得、変更、または削除できます。 Webアプリケーションでは、これらの要件は、ユーザーが新しい投稿を追加したり、投稿を削除したり、アカウントを削除したりする場合があります。これにより、投稿が削除される場合と削除されない場合があります。 データを操作するために実行するアクションは、アプリケーションの特定の機能によって異なります。 たとえば、タイトルのない投稿をユーザーに追加させたくない場合があります。

Flaskは、Python言語でWebアプリケーションを作成するための便利なツールと機能を提供する軽量のPythonWebフレームワークです。 MongoDB は、 JSON のようなドキュメントを使用してデータを格納する、汎用のドキュメント指向のNoSQLデータベースプログラムです。 リレーショナルデータベースで使用される表形式のリレーションとは異なり、JSONのようなドキュメントでは、シンプルさを維持しながら柔軟で動的なスキーマを使用できます。 一般に、NoSQLデータベースは水平方向に拡張できるため、ビッグデータやリアルタイムアプリケーションに適しています。

このチュートリアルでは、PythonでMongoDBデータベースと対話できるようにするMongoDBデータベースドライバーであるPyMongoライブラリの使用方法を示す小さなtodoリストWebアプリケーションを作成します。 これをFlaskで使用して、データベースサーバーへの接続、MongoDBにドキュメントのグループを格納するコレクションの作成、コレクションへのデータの挿入、コレクションからのデータの取得と削除などの基本的なタスクを実行します。

前提条件

ステップ1—PyMongoとFlaskを設定する

このステップでは、FlaskとPyMongoライブラリをインストールします。

仮想環境をアクティブにして、 pip FlaskとPyMongoをインストールするには:

  1. pip install Flask pymongo

インストールが正常に完了すると、出力の最後に次のような行が表示されます。

Output
Successfully installed Flask-2.0.2 Jinja2-3.0.3 MarkupSafe-2.0.1 Werkzeug-2.0.2 click-8.0.3 itsdangerous-2.0.1 pymongo-4.0.1

必要なPythonパッケージをインストールしたので、MongoDBサーバーに接続してコレクションを作成します。

ステップ2—MongoDBサーバーに接続してコレクションを作成する

このステップでは、PyMongoライブラリを使用して、MongoDBサーバーとの対話に使用するクライアントを作成し、データベースを作成してから、タスクを保存するためのコレクションを作成します。

プログラミング環境をアクティブにして、次のファイルを開きます。 app.py あなたの中で編集するため flask_app ディレクトリ:

  1. nano app.py

このファイルは、FlaskとPyMongoライブラリから必要なクラスとヘルパーをインポートします。 MongoDBサーバーと対話して、データベースを作成し、todoのコレクションを作成します。 次のコードをに追加します app.py:

フラスコ_app/app.py
from flask import Flask
from pymongo import MongoClient

app = Flask(__name__)

client = MongoClient('localhost', 27017)

db = client.flask_db
todos = db.todos

ファイルを保存して閉じます。

ここでインポートします Flask クラス。これを使用して、Flaskアプリケーションインスタンスを作成します。 app.

をインポートします MongoClient これを使用して、MongoDBインスタンスのクライアントオブジェクトを作成します。 client、これにより、MongoDBサーバーに接続して対話することができます。 インスタンス化すると MongoClient()、MongoDBサーバーのホストを渡します。 localhost 私たちの場合、そしてポートは 27017 ここ。

ノート:

Ubuntu 20.04でMongoDBを保護する方法のガイドに従って、MongoDBインストールのセキュリティを強化することを強くお勧めします。 保護されたら、リモート接続を受け入れるようにMongoDBを構成できます

MongoDBで認証を有効にしたら、追加のパスを渡す必要があります usernamepassword のインスタンスを作成するときのパラメータ MongoClient() そのようです:

client = MongoClient('localhost', 27017, username='username', password='password')

次に、 client と呼ばれるMongoDBデータベースを作成するインスタンス flask_db それへの参照をという変数に保存します db.

次に、というコレクションを作成します todosflask_db を使用したデータベース db 変数。 コレクションは、リレーショナルデータベースのテーブルのように、ドキュメントのグループをMongoDBに格納します。

MongoDBでは、データベースとコレクションは遅延して作成されます。 つまり、実行しても app.py ファイルの場合、最初のドキュメントが作成されるまで、データベースに関連するコードは実際には実行されません。 ユーザーがtodoドキュメントを自分のに挿入できるページを備えた小さなFlaskアプリケーションを作成します todos 次のステップで収集します。 最初のtodoドキュメントが追加されると、 flask_db データベースと todos コレクションはMongoDBサーバーに作成されます。

現在のデータベースのリストを取得するには、新しいターミナルを開いて、 mongo 次のコマンドを使用してシェルを作成します。

  1. mongo

プロンプトが開きます。次のコマンドを使用してデータベースを確認できます。

  1. show dbs

これがMongoDBの新規インストールである場合、出力には、 admin, config、 と local データベース。

あなたはそれに気付くでしょう flask_db まだ存在していません。 出て mongo ターミナルウィンドウで実行されているシェルを使用して、次の手順に進みます。

ステップ3—Todoを追加および表示するためのWebページを作成する

このステップでは、ユーザーがToDoを追加して同じページに表示できるWebフォームを使用してWebページを作成します。

プログラミング環境をアクティブにして、 app.py 編集用ファイル:

  1. nano app.py

まず、次のインポートを追加します flask:

フラスコ_app/app.py
from flask import Flask, render_template, request, url_for, redirect
from pymongo import MongoClient

# ...

ここでは、 render_template() HTMLテンプレートのレンダリングに使用するヘルパー関数 request ユーザーが送信するデータにアクセスするためのオブジェクト、 url_for() URLを生成する関数、および redirect() ToDoを追加した後、ユーザーをインデックスページにリダイレクトする関数。

次に、ファイルの最後に次のルートを追加します。

フラスコ_app/app.py
# ...


@app.route('/', methods=('GET', 'POST'))
def index():
    return render_template('index.html')

ファイルを保存して閉じます。

このルートでは、タプルを渡します ('GET', 'POST')methods GET要求とPOST要求の両方を許可するパラメーター。 GETリクエストは、サーバーからデータを取得するために使用されます。 POSTリクエストは、特定のルートにデータを投稿するために使用されます。 デフォルトでは、GETリクエストのみが許可されます。 ユーザーが最初にリクエストしたとき / GETリクエストを使用してルーティングします。 index.html レンダリングされます。 後でこのルートを編集して、ユーザーが新しいToDoを作成するためのWebフォームに入力して送信するときのPOSTリクエストを処理します。

次に、テンプレートフォルダを作成します flask_app ディレクトリ、および index.html 前のルートで参照したテンプレート:

  1. mkdir templates
  2. nano templates/index.html

内に次のコードを追加します index.html ファイル:

フラスコ_app/templates / index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FlaskApp</title>
    <style>
        .todo {
            padding: 20px;
            margin: 10px;
            background-color: #eee;
        }
    </style>
</head>
<body>
    <h1>FlaskTODO</h1>
    <hr>
    <div class="content">
    <form method="post">
        <p>
            <b><label for="content">Todo content</label></b>
        </p>
        <p>
            <input type="text" name="content"
                placeholder="Todo Content"></input>
        </p>

        <p>
            <b><label for="degree">Degree</label></b>
        </p>
        <p>
            <input id="degree-0" name="degree" required type="radio" value="Important">
            <label for="degree-0">Important</label>
        </p>
        <p>
            <input id="degree-1" name="degree" required type="radio" value="Unimportant">
            <label for="degree-1">Unimportant</label>
        </p>
        <button type="submit">Submit</button>
    </form>
    </div>
</body>
</html>

ファイルを保存して閉じます。

ここに、タイトル、いくつかのスタイル、見出し、およびWebフォームを含む基本的なHTMLページがあります。 Webフォームで、 method に属性 post フォームがPOSTリクエストを送信することを示します。 ToDoコンテンツ用のテキスト入力フィールドがあります。 content、のタイトルデータにアクセスするために使用します / ルート。 また、名前が付いた2つのHTMLラジオボタンがあります degree、これにより、ユーザーは各ToDoアイテムの重要度を指定できます。Todoを作成するときに、ImportantオプションまたはUnimportantオプションのいずれかを選択できます。 最後に、フォームの最後に送信ボタンがあります。

あなたの中に flask_app 仮想環境がアクティブ化されているディレクトリ、アプリケーションについてFlaskに通知します(app.py この場合)を使用して FLASK_APP 環境変数。 次に、 FLASK_ENV 環境変数から development アプリケーションを開発モードで実行し、デバッガーにアクセスします。 Flaskデバッガーの詳細については、Flaskアプリケーションでエラーを処理する方法を参照してください。 これを行うには、次のコマンドを使用します。

  1. export FLASK_APP=app
  2. export FLASK_ENV=development

次に、アプリケーションを実行します。

  1. flask run

注: ModuleNotFoundError: No module named 'pymongo' アプリケーションを実行しようとするとエラーが発生します。 これを修正するには、仮想環境を非アクティブ化してから再アクティブ化します。 次に、を実行します flask run もう一度コマンドします。

開発サーバーが実行されている状態で、ブラウザーを使用して次のURLにアクセスします。

http://127.0.0.1:5000/

ToDoコンテンツの入力フィールド、重要度の2つのラジオボタン、および送信ボタンのあるインデックスページが表示されます。

Webフォームの詳細については、FlaskアプリケーションでWebフォームを使用する方法を参照してください。 Webフォームを管理するためのより高度で安全な方法については、Flask-WTFを使用してWebフォームを使用および検証する方法を参照してください。

フォームに入力して送信し、サーバーにPOSTリクエストを送信すると、POSTリクエストを処理しなかったため、何も起こりません。 / ルート。

サーバーを実行したままにして、新しいターミナルウィンドウを開きます。

開ける app.py ユーザーが送信したPOSTリクエストを処理するには、それらをtodosコレクションに追加し、インデックスページに表示します。

  1. nano app.py

編集します / 次のように見えるルート:

フラスコ_app/app.py

@app.route('/', methods=('GET', 'POST'))
def index():
    if request.method=='POST':
        content = request.form['content']
        degree = request.form['degree']
        todos.insert_one({'content': content, 'degree': degree})
        return redirect(url_for('index'))

    all_todos = todos.find()
    return render_template('index.html', todos=all_todos)

ファイルを保存して閉じます。

これらの変更では、POSTリクエストを内部で処理します if request.method == 'POST' 調子。 ユーザーが送信するToDoコンテンツと重要度を request.form 物体。

todosコレクションでinsert_one()メソッドを使用して、todoドキュメントを追加します。 Pythonディクショナリでtodoデータを提供し、 'content' ユーザーがtodoコンテンツのテキストフィールドに送信した値に変更し、 'degree' ユーザーが選択したラジオボタンの値のキー。 次に、インデックスページにリダイレクトします。これにより、ページが更新され、新しく追加されたToDoアイテムが表示されます。

保存されたすべてのToDoを表示するには、POSTリクエストの処理を担当するコードの外部で find()メソッドを使用します。これにより、 todos コレクション。 データベースから取得したToDoをと呼ばれる変数に保存します all_todos、次に編集します render_template() ToDoドキュメントのリストをに渡すための関数呼び出し index.html テンプレート。これは、テンプレートの次の変数で使用できます。 todos.

インデックスページを更新すると、ブラウザからフォームの再送信の確認を求めるメッセージが表示される場合があります。 同意すると、POSTリクエストを処理する前に以前に送信したToDoアイテムがデータベースに追加されます。これは、フォームを処理するためのコードがルートに存在するためです。

インデックスページにはまだToDoアイテムを表示するコードがないため、追加したアイテムは表示されません。 ブラウザにフォームの再送信を許可した場合は、mongoシェルを開き、に接続することで、新しく追加されたデータを確認できます。 flask_db 次のコマンドを使用してデータベースを作成します。

  1. use flask_db

次に、 find() データベース内のすべてのtodoアイテムを取得する関数:

  1. db.todos.find()

データが再送信された場合は、ここの出力に表示されます。

次に、 index.html の内容を表示するためのテンプレート todos あなたがそれに渡したリスト:

  1. nano templates/index.html

を追加してファイルを編集します <hr> ブレークし、フォームの後に Jinja for loop を追加して、ファイルが次のようになるようにします。

フラスコ_app/templates / index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FlaskApp</title>
    <style>
        .todo {
            padding: 20px;
            margin: 10px;
            background-color: #eee;
        }
    </style>
</head>
<body>
    <h1>FlaskTODO</h1>
    <hr>
    <div class="content">
    <form method="post">
        <p>
            <b><label for="content">Todo content</label></b>
        </p>
        <p>
            <input type="text" name="content"
                placeholder="Todo Content"></input>
        </p>

        <p>
            <b><label for="degree">Degree</label></b>
        </p>
        <p>
            <input id="degree-0" name="degree" required type="radio" value="Important">
            <label for="degree-0">Important</label>
        </p>
        <p>
            <input id="degree-1" name="degree" required type="radio" value="Unimportant">
            <label for="degree-1">Unimportant</label>
        </p>
        <button type="submit">Submit</button>
    </form>
    <hr>
    {% for todo in todos %}
        <div class="todo">
            <p>{{ todo['content'] }} <i>({{ todo['degree']}})</i></p>
        </div>
    {% endfor %}

    </div>
</body>
</html>

ファイルを保存して閉じます。

このファイルに、 <hr> WebフォームとToDoのリストを区切るタグ。

あなたは for 行のループ {% for todo in todos %} の各ToDoアイテムを確認する todos リスト。 ToDoの内容と重要度を内部に表示します <p> 鬼ごっこ。

次に、インデックスページを更新し、Webフォームに入力して、送信します。 フォームの下に追加したToDoが表示されます。 次に、ユーザーが既存のToDoを削除できるようにするボタンを追加します。

ステップ4—Todoを削除する

このステップでは、ユーザーがボタンを使用してToDoを削除できるルートを追加します。

まず、新しいものを追加します /id/delete POSTリクエストを受け入れるルート。 あなたの新しい delete() ビュー関数は、URLから削除するToDoのIDを受け取り、そのIDを使用して削除します。

ToDoを削除するには、そのIDを文字列として取得し、コレクションのdeleteメソッドに渡す前にObjectIdに変換する必要があります。 したがって、インポートする必要があります ObjectId() bsonモジュールのクラス。BSON(バイナリJSON)のエンコードとデコードを処理します。

開ける app.py 編集用:

  1. nano app.py

まず、ファイルの先頭に次のインポートを追加します。

フラスコ_app/app.py
from bson.objectid import ObjectId

# ...

これは ObjectId() 文字列IDをObjectIdオブジェクトに変換するために使用するクラス。

次に、最後に次のルートを追加します。

フラスコ_app/app.py

# ...


@app.post('/<id>/delete/')
def delete(id):
    todos.delete_one({"_id": ObjectId(id)})
    return redirect(url_for('index'))

ファイルを保存して閉じます。

ここでは、通常の代わりに app.route デコレータでは、Flaskバージョン2.0.0で導入されたapp.post デコレータを使用します。これにより、一般的なHTTPメソッドのショートカットが追加されました。 例えば、 @app.post("/login") のショートカットです @app.route("/login", methods=["POST"]). これは、このビュー関数がPOSTリクエストのみを受け入れ、 /ID/delete ブラウザのルートは 405 Method Not Allowed エラー。WebブラウザはデフォルトでGETリクエストを使用しているためです。 ToDoを削除するには、ユーザーはこのルートにPOSTリクエストを送信するボタンをクリックします。

この関数は、削除するToDoドキュメントのIDを受け取ります。 このIDをdelete_one()メソッドに渡します。 todos コレクションを作成し、受け取った文字列IDをObjectIdに変換します。 ObjectId() 以前にインポートしたクラス。

ToDoドキュメントを削除した後、ユーザーをインデックスページにリダイレクトします。

次に、 index.html Todoの削除ボタンを追加するためのテンプレート:

  1. nano templates/index.html

編集します for 新しいを追加してループする <form> 鬼ごっこ:

フラスコ_app/templates / index.html

    {% for todo in todos %}
        <div class="todo">
            <p>{{ todo['content'] }} <i>({{ todo['degree']}})</i></p>
            <form method="POST" action="{{ url_for('delete', id=todo['_id']) }}" >
                <input type="submit" value="Delete Todo"
                       onclick="return confirm('Are you sure you want to delete this entry?')">
            </form>
        </div>
    {% endfor %}

ファイルを保存して閉じます。

ここに、POSTリクエストを送信するWebフォームがあります。 delete() ビュー機能。 あなたは合格します todo['_id'] 削除するToDoを指定します。 Webブラウザーで使用可能なconfirm()メソッドを使用して、要求を送信する前に確認メッセージを表示します。

インデックスページを更新すると、各Todoアイテムの下に DeleteTodoボタンが表示されます。 それをクリックして、削除を確認します。 インデックスページにリダイレクトされ、todoは表示されなくなります。

これで、FlaskアプリケーションのmongoDBデータベースから不要なToDoを削除する方法があります。

削除を確認するには、mongoシェルを開き、 find() 関数:

  1. db.todos.find()

削除したアイテムがもうあなたの中にないことを確認する必要があります todos コレクション。

結論

MongoDBデータベースと通信するtodoを管理するための小さなFlaskWebアプリケーションを構築しました。 MongoDBデータベースサーバーに接続する方法、ドキュメントのグループを格納するコレクションを作成する方法、コレクションにデータを挿入する方法、コレクションからデータを取得および削除する方法を学習しました。

Flaskの詳細については、Flaskを使用してWebサイトを作成する方法シリーズの他のチュートリアルをご覧ください。

MongoDBの詳細については、MongoDBチュートリアルシリーズでデータを管理する方法を参照してください。

モバイルバージョンを終了