序章
Webアプリケーションでは、通常、データの組織化されたコレクションであるデータベースが必要です。 データベースを使用して、効率的に取得および操作できる永続データを保存および維持します。 たとえば、ソーシャルメディアアプリケーションでは、ユーザーデータ(個人情報、投稿、コメント、フォロワー)が効率的に操作できる方法で保存されているデータベースがあります。 さまざまな要件や条件に応じて、データベースにデータを追加、取得、変更、または削除できます。 Webアプリケーションでは、これらの要件は、ユーザーが新しい投稿を追加したり、投稿を削除したり、アカウントを削除したりする場合があります。これにより、投稿が削除される場合と削除されない場合があります。 データを操作するために実行するアクションは、アプリケーションの特定の機能によって異なります。 たとえば、タイトルのない投稿をユーザーに追加させたくない場合があります。
Flaskは、Python言語でWebアプリケーションを作成するための便利なツールと機能を提供する軽量のPythonWebフレームワークです。 MongoDB は、 JSON のようなドキュメントを使用してデータを格納する、汎用のドキュメント指向のNoSQLデータベースプログラムです。 リレーショナルデータベースで使用される表形式のリレーションとは異なり、JSONのようなドキュメントでは、シンプルさを維持しながら柔軟で動的なスキーマを使用できます。 一般に、NoSQLデータベースは水平方向に拡張できるため、ビッグデータやリアルタイムアプリケーションに適しています。
このチュートリアルでは、PythonでMongoDBデータベースと対話できるようにするMongoDBデータベースドライバーであるPyMongoライブラリの使用方法を示す小さなtodoリストWebアプリケーションを作成します。 これをFlaskで使用して、データベースサーバーへの接続、MongoDBにドキュメントのグループを格納するコレクションの作成、コレクションへのデータの挿入、コレクションからのデータの取得と削除などの基本的なタスクを実行します。
前提条件
-
ローカルのPython3プログラミング環境については、 Python3シリーズのローカルプログラミング環境をインストールしてセットアップする方法のチュートリアルに従ってください。 このチュートリアルでは、プロジェクトディレクトリを呼び出します
flask_app
. -
ローカルマシンにインストールされたMongoDB。 Ubuntu 20.04にMongoDBをインストールする方法ガイドに従って、MongoDBデータベースをセットアップします。
-
ルート、ビュー関数、テンプレートなどの基本的なFlaskの概念の理解。 Flaskに慣れていない場合は、FlaskとPythonを使用して最初のWebアプリケーションを作成する方法およびFlaskアプリケーションでテンプレートを使用する方法を確認してください。
-
基本的なHTMLの概念の理解。 背景知識については、HTMLを使用してWebサイトを構築する方法チュートリアルシリーズを確認できます。
ステップ1—PyMongoとFlaskを設定する
このステップでは、FlaskとPyMongoライブラリをインストールします。
仮想環境をアクティブにして、 pip
FlaskとPyMongoをインストールするには:
- 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
ディレクトリ:
- nano app.py
このファイルは、FlaskとPyMongoライブラリから必要なクラスとヘルパーをインポートします。 MongoDBサーバーと対話して、データベースを作成し、todoのコレクションを作成します。 次のコードをに追加します 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で認証を有効にしたら、追加のパスを渡す必要があります username
と password
のインスタンスを作成するときのパラメータ MongoClient()
そのようです:
client = MongoClient('localhost', 27017, username='username', password='password')
次に、 client
と呼ばれるMongoDBデータベースを作成するインスタンス flask_db
それへの参照をという変数に保存します db
.
次に、というコレクションを作成します todos
に flask_db
を使用したデータベース db
変数。 コレクションは、リレーショナルデータベースのテーブルのように、ドキュメントのグループをMongoDBに格納します。
MongoDBでは、データベースとコレクションは遅延して作成されます。 つまり、実行しても app.py
ファイルの場合、最初のドキュメントが作成されるまで、データベースに関連するコードは実際には実行されません。 ユーザーがtodoドキュメントを自分のに挿入できるページを備えた小さなFlaskアプリケーションを作成します todos
次のステップで収集します。 最初のtodoドキュメントが追加されると、 flask_db
データベースと todos
コレクションはMongoDBサーバーに作成されます。
現在のデータベースのリストを取得するには、新しいターミナルを開いて、 mongo
次のコマンドを使用してシェルを作成します。
- mongo
プロンプトが開きます。次のコマンドを使用してデータベースを確認できます。
- show dbs
これがMongoDBの新規インストールである場合、出力には、 admin
, config
、 と local
データベース。
あなたはそれに気付くでしょう flask_db
まだ存在していません。 出て mongo
ターミナルウィンドウで実行されているシェルを使用して、次の手順に進みます。
ステップ3—Todoを追加および表示するためのWebページを作成する
このステップでは、ユーザーがToDoを追加して同じページに表示できるWebフォームを使用してWebページを作成します。
プログラミング環境をアクティブにして、 app.py
編集用ファイル:
- nano app.py
まず、次のインポートを追加します flask
:
from flask import Flask, render_template, request, url_for, redirect
from pymongo import MongoClient
# ...
ここでは、 render_template()
HTMLテンプレートのレンダリングに使用するヘルパー関数 request
ユーザーが送信するデータにアクセスするためのオブジェクト、 url_for()
URLを生成する関数、および redirect()
ToDoを追加した後、ユーザーをインデックスページにリダイレクトする関数。
次に、ファイルの最後に次のルートを追加します。
# ...
@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
前のルートで参照したテンプレート:
- mkdir templates
- nano templates/index.html
内に次のコードを追加します 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アプリケーションでエラーを処理する方法を参照してください。 これを行うには、次のコマンドを使用します。
- export FLASK_APP=app
- export FLASK_ENV=development
次に、アプリケーションを実行します。
- 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コレクションに追加し、インデックスページに表示します。
- nano 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
次のコマンドを使用してデータベースを作成します。
- use flask_db
次に、 find()
データベース内のすべてのtodoアイテムを取得する関数:
- db.todos.find()
データが再送信された場合は、ここの出力に表示されます。
次に、 index.html
の内容を表示するためのテンプレート todos
あなたがそれに渡したリスト:
- nano templates/index.html
を追加してファイルを編集します <hr>
ブレークし、フォームの後に Jinja for loop を追加して、ファイルが次のようになるようにします。
<!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
編集用:
- nano app.py
まず、ファイルの先頭に次のインポートを追加します。
from bson.objectid import ObjectId
# ...
これは ObjectId()
文字列IDをObjectIdオブジェクトに変換するために使用するクラス。
次に、最後に次のルートを追加します。
# ...
@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の削除ボタンを追加するためのテンプレート:
- nano templates/index.html
編集します for
新しいを追加してループする <form>
鬼ごっこ:
{% 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()
関数:
- db.todos.find()
削除したアイテムがもうあなたの中にないことを確認する必要があります todos
コレクション。
結論
MongoDBデータベースと通信するtodoを管理するための小さなFlaskWebアプリケーションを構築しました。 MongoDBデータベースサーバーに接続する方法、ドキュメントのグループを格納するコレクションを作成する方法、コレクションにデータを挿入する方法、コレクションからデータを取得および削除する方法を学習しました。
Flaskの詳細については、Flaskを使用してWebサイトを作成する方法シリーズの他のチュートリアルをご覧ください。
MongoDBの詳細については、MongoDBチュートリアルシリーズでデータを管理する方法を参照してください。