FlaskおよびSQLiteで1対多のデータベース関係を使用する方法
著者はCOVID-19救済基金を選択し、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
Flask は、Python言語を使用してWebアプリケーションを構築するためのフレームワークであり、 SQLite は、Pythonでアプリケーションデータを格納するために使用できるデータベースエンジンです。 このチュートリアルでは、FlaskとSQLiteを使用して、ユーザーがToDoアイテムのリストを作成できるToDoアプリケーションを作成します。 FlaskでSQLiteを使用する方法と、1対多のデータベース関係がどのように機能するかを学習します。
1対多のデータベース関係は、あるテーブルのレコードが別のテーブルの複数のレコードを参照できる2つのデータベーステーブル間の関係です。 たとえば、ブログアプリケーションでは、投稿を保存するためのテーブルは、コメントを保存するためのテーブルと1対多の関係を持つことができます。 各投稿は多くのコメントを参照でき、各コメントは1つの投稿を参照します。 したがって、 1つの投稿は、多くのコメントと関係があります。 postテーブルは親テーブルであり、commentsテーブルは子テーブルです。親テーブルのレコードは、子テーブルの多くのレコードを参照できます。 これは、各テーブルの関連データにアクセスできるようにするために重要です。
SQLiteは移植性があり、Pythonで動作するために追加の設定を必要としないため、SQLiteを使用します。 また、MySQLやPostgresなどのより大きなデータベースに移動する前にアプリケーションのプロトタイプを作成する場合にも最適です。 適切なデータベースシステムを選択する方法の詳細については、 SQLiteとMySQLとPostgreSQL:リレーショナルデータベース管理システムの比較の記事を参照してください。
前提条件
このガイドに従う前に、次のものが必要です。
- ローカルPython3プログラミング環境については、ローカルマシン用のPython3シリーズのローカルプログラミング環境をインストールおよびセットアップする方法のチュートリアルに従ってください。 このチュートリアルでは、プロジェクトディレクトリを
flask_todo
と呼びます。 - ルートの作成、HTMLテンプレートのレンダリング、SQLiteデータベースへの接続などの基本的なFlaskの概念の理解。 これらの概念に精通していない場合は、 Python 3でFlaskを使用してWebアプリケーションを作成する方法に従うことができますが、必須ではありません。
ステップ1—データベースの作成
このステップでは、プログラミング環境をアクティブ化し、Flaskをインストールし、SQLiteデータベースを作成して、サンプルデータを入力します。 外部キーを使用して、リストとアイテムの間に1対多の関係を作成する方法を学習します。 外部キーは、データベーステーブルを別のテーブルに関連付けるために使用されるキーであり、子テーブルとその親テーブルの間のリンクです。
プログラミング環境をまだアクティブ化していない場合は、プロジェクトディレクトリ(flask_todo
)にいることを確認し、次のコマンドを使用してアクティブ化します。
source env/bin/activate
プログラミング環境がアクティブ化されたら、次のコマンドを使用してFlaskをインストールします。
pip install flask
インストールが完了すると、ToDoデータを格納するために必要なテーブルを作成するためのSQLコマンドを含むデータベーススキーマファイルを作成できるようになります。 ToDoリストを格納するためのlists
というテーブルと、各リストの項目を格納するためのitems
テーブルの2つのテーブルが必要になります。
flask_todo
ディレクトリ内にあるschema.sql
というファイルを開きます。
nano schema.sql
このファイル内に次のSQLコマンドを入力します。
フラスコ_todo/schema.sql
DROP TABLE IF EXISTS lists; DROP TABLE IF EXISTS items; CREATE TABLE lists ( id INTEGER PRIMARY KEY AUTOINCREMENT, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, title TEXT NOT NULL ); CREATE TABLE items ( id INTEGER PRIMARY KEY AUTOINCREMENT, list_id INTEGER NOT NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, content TEXT NOT NULL, FOREIGN KEY (list_id) REFERENCES lists (id) );
ファイルを保存して閉じます。
最初の2つのSQLコマンドはDROP TABLE IF EXISTS lists;
とDROP TABLE IF EXISTS items;
です。これらは、lists
とitems
という名前の既存のテーブルを削除するため、混乱を招く動作は見られません。 これにより、これらのSQLコマンドを使用するたびにデータベースにあるすべてのコンテンツが削除されるため、このチュートリアルを終了して最終結果を試すまで、Webアプリケーションに重要なコンテンツを書き込まないようにしてください。
次に、CREATE TABLE lists
を使用して、次の列を持つTo Doリスト(学習リスト、作業リスト、ホームリストなど)を格納するlists
テーブルを作成します。
id
:主キーを表す整数。これには、各エントリのデータベースによって一意の値が割り当てられます(つまり、 やることリスト)。created
:やることリストが作成された時刻。NOT NULL
は、この列が空であってはならないことを意味し、DEFAULT
値はCURRENT_TIMESTAMP
値であり、リストがデータベースに追加された時刻です。id
と同様に、この列の値は自動的に入力されるため、指定する必要はありません。title
:リストのタイトル。
次に、items
というテーブルを作成して、やること項目を保存します。 このテーブルには、ID、アイテムが属するリストを識別するためのlist_id
整数列、作成日、およびアイテムのコンテンツがあります。 アイテムをデータベース内のリストにリンクするには、外部キー制約と行FOREIGN KEY (list_id) REFERENCES lists (id)
を使用します。 ここで、lists
テーブルは親テーブルであり、外部キー制約によって参照されているテーブルです。これは、リストに複数のアイテムを含めることができることを示しています。 items
テーブルは、子テーブルであり、制約が適用されるテーブルです。 これは、アイテムが単一のリストに属していることを意味します。 list_id
列は、lists
親テーブルのid
列を参照します。
リストには多くのアイテムを含めることができ、アイテムは 1つのリストにのみ属するため、lists
テーブルとitems
テーブルの関係は[ X155X]1対多の関係。
次に、schema.sql
ファイルを使用してデータベースを作成します。 flask_todo
ディレクトリ内のinit_db.py
という名前のファイルを開きます。
nano init_db.py
次に、次のコードを追加します。
フラスコ_todo/init_db.py
import sqlite3 connection = sqlite3.connect('database.db') with open('schema.sql') as f: connection.executescript(f.read()) cur = connection.cursor() cur.execute("INSERT INTO lists (title) VALUES (?)", ('Work',)) cur.execute("INSERT INTO lists (title) VALUES (?)", ('Home',)) cur.execute("INSERT INTO lists (title) VALUES (?)", ('Study',)) cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)", (1, 'Morning meeting') ) cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)", (2, 'Buy fruit') ) cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)", (2, 'Cook dinner') ) cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)", (3, 'Learn Flask') ) cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)", (3, 'Learn SQLite') ) connection.commit() connection.close()
ファイルを保存して閉じます。
ここでは、このプログラムを実行すると作成されるdatabase.db
というファイルに接続します。 次に、schema.sql
ファイルを開き、複数のSQLステートメントを同時に実行する executescript()メソッドを使用して実行します。
schema.sql
を実行すると、lists
テーブルとitems
テーブルが作成されます。 次に、カーソルオブジェクトを使用して、いくつかのINSERT
SQLステートメントを実行し、3つのリストと5つのToDo項目を作成します。
list_id
列を使用して、リストのid
値を介して各アイテムをリストにリンクします。 たとえば、Work
リストはデータベースへの最初の挿入であるため、IDは1
になります。 これは、Morning meeting
タスクアイテムをWork
にリンクする方法です。同じルールが他のリストとアイテムにも適用されます。
最後に、変更をコミットして接続を閉じます。
プログラムを実行します。
python init_db.py
実行後、database.db
という新しいファイルがflask_todo
ディレクトリに表示されます。
環境をアクティブ化し、Flaskをインストールし、SQLiteデータベースを作成しました。 次に、データベースからリストとアイテムを取得し、アプリケーションのホームページに表示します。
ステップ2—やること項目の表示
このステップでは、前のステップで作成したデータベースを、やることリストと各リストの項目を表示するFlaskアプリケーションに接続します。 SQLite結合を使用して2つのテーブルからデータをクエリする方法と、ToDo項目をリストごとにグループ化する方法を学習します。
まず、アプリケーションファイルを作成します。 flask_todo
ディレクトリ内のapp.py
という名前のファイルを開きます。
nano app.py
次に、次のコードをファイルに追加します。
フラスコ_todo/app.py
from itertools import groupby import sqlite3 from flask import Flask, render_template, request, flash, redirect, url_for def get_db_connection(): conn = sqlite3.connect('database.db') conn.row_factory = sqlite3.Row return conn app = Flask(__name__) app.config['SECRET_KEY'] = 'this should be a secret random string' @app.route('/') def index(): conn = get_db_connection() todos = conn.execute('SELECT i.content, l.title FROM items i JOIN lists l \ ON i.list_id = l.id ORDER BY l.title;').fetchall() lists = {} for k, g in groupby(todos, key=lambda t: t['title']): lists[k] = list(g) conn.close() return render_template('index.html', lists=lists)
ファイルを保存して閉じます。
get_db_connection()
関数は、database.db
データベースファイルへの接続を開き、row_factory属性をsqlite3.Row
に設定します。 このようにして、名前に基づいて列にアクセスできます。 これは、データベース接続が通常のPythonディクショナリのように動作する行を返すことを意味します。 最後に、この関数は、データベースへのアクセスに使用するconn
接続オブジェクトを返します。
index()
ビュー機能で、データベース接続を開き、次のSQLクエリを実行します。
SELECT i.content, l.title FROM items i JOIN lists l ON i.list_id = l.id ORDER BY l.title;
次に、fetchall()
メソッドを使用して結果を取得し、todos
という変数にデータを保存します。
このクエリでは、SELECT
を使用して、items
テーブルとlists
テーブルの両方を(テーブルと結合して)アイテムのコンテンツとアイテムが属するリストのタイトルを取得します。 items
のエイリアスi
およびlists
のエイリアスl
)。 ON
キーワードの後に結合条件i.list_id = l.id
を指定すると、items
テーブルの各行と、lists
テーブルのすべての行が取得されます。 items
テーブルの]列は、lists
テーブルのid
と一致します。 次に、ORDER BY
を使用して、リストのタイトルで結果を並べ替えます。
このクエリをよりよく理解するには、flask_todo
ディレクトリでPythonREPLを開きます。
python
SQLクエリを理解するには、次の小さなプログラムを実行してtodos
変数の内容を調べます。
from app import get_db_connection conn = get_db_connection() todos = conn.execute('SELECT i.content, l.title FROM items i JOIN lists l \ ON i.list_id = l.id ORDER BY l.title;').fetchall() for todo in todos: print(todo['title'], ':', todo['content'])
最初にapp.py
ファイルからget_db_connection
をインポートし、次に接続を開いてクエリを実行します(これは、app.py
ファイルにあるSQLクエリと同じであることに注意してください)。 for
ループでは、リストのタイトルと各ToDo項目の内容を出力します。
出力は次のようになります。
OutputHome : Buy fruit Home : Cook dinner Study : Learn Flask Study : Learn SQLite Work : Morning meeting
CTRL + D
を使用してREPLを閉じます。
SQL結合がどのように機能し、クエリが何を達成するかを理解したところで、app.py
ファイルのindex()
ビュー関数に戻りましょう。 todos
変数を宣言した後、次のコードを使用して結果をグループ化します。
lists = {} for k, g in groupby(todos, key=lambda t: t['title']): lists[k] = list(g)
最初にlists
という空の辞書を宣言し、次にfor
ループを使用して、todos
変数の結果をリストのタイトルでグループ化します。 itertools
標準ライブラリからインポートしたgroupby()関数を使用します。 この関数は、todos
変数の各項目を調べ、for
ループの各キーの結果のグループを生成します。
k
は、key
に渡した関数を使用して抽出されたリストタイトル(つまり、Home
、Study
、Work
)を表します。 ]groupby()
関数のパラメーター。 この場合、関数はlambda t: t['title']
であり、To Do項目を受け取り、リストのタイトルを返します(前のforループのtodo['title']
で行ったように)。 g
は、各リストタイトルのやること項目を含むグループを表します。 たとえば、最初の反復では、k
は'Home'
になり、g
はアイテム'Buy fruit'
を含む反復可能になります。および'Cook dinner'
。
これにより、リストとアイテム間の1対多の関係を表すことができます。各リストのタイトルには、いくつかのToDoアイテムがあります。
app.py
ファイルを実行し、for
ループの実行が終了すると、lists
は次のようになります。
Output{'Home': [<sqlite3.Row object at 0x7f9f58460950>, <sqlite3.Row object at 0x7f9f58460c30>], 'Study': [<sqlite3.Row object at 0x7f9f58460b70>, <sqlite3.Row object at 0x7f9f58460b50>], 'Work': [<sqlite3.Row object at 0x7f9f58460890>]}
各sqlite3.Row
オブジェクトには、index()
関数のSQLクエリを使用してitems
テーブルから取得したデータが含まれます。 このデータをより適切に表現するために、lists
ディクショナリを調べて、各リストとそのアイテムを表示するプログラムを作成しましょう。
flask_todo
ディレクトリにあるlist_example.py
というファイルを開きます。
nano list_example.py
次に、次のコードを追加します。
フラスコ_todo/list_example.py
from itertools import groupby from app import get_db_connection conn = get_db_connection() todos = conn.execute('SELECT i.content, l.title FROM items i JOIN lists l \ ON i.list_id = l.id ORDER BY l.title;').fetchall() lists = {} for k, g in groupby(todos, key=lambda t: t['title']): lists[k] = list(g) for list_, items in lists.items(): print(list_) for item in items: print(' ', item['content'])
ファイルを保存して閉じます。
これは、index()
ビュー機能の内容と非常によく似ています。 ここでの最後のfor
ループは、lists
ディクショナリがどのように構成されているかを示しています。 最初に辞書の項目を調べ、リストのタイトル(list_
変数にあります)を印刷し、次にリストに属するTo Do項目の各グループを調べて、項目のコンテンツ値を印刷します。
list_example.py
プログラムを実行します。
python list_example.py
list_example.py
の出力は次のとおりです。
OutputHome Buy fruit Cook dinner Study Learn Flask Learn SQLite Work Morning meeting
index()
関数の各部分を理解したところで、ベーステンプレートを作成し、return render_template('index.html', lists=lists)
行を使用してレンダリングしたindex.html
ファイルを作成しましょう。
flask_todo
ディレクトリに、templates
ディレクトリを作成し、その中にbase.html
というファイルを開きます。
mkdir templates nano templates/base.html
base.html
内に次のコードを追加します。ここでは、Bootstrapを使用していることに注意してください。 FlaskのHTMLテンプレートに慣れていない場合は、 Python3でFlaskを使用してWebアプリケーションを作成する方法のステップ3を参照してください。
フラスコ_todo/templates / base.html
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <title>{% block title %} {% endblock %}</title> </head> <body> <nav class="navbar navbar-expand-md navbar-light bg-light"> <a class="navbar-brand" href="{{ url_for('index')}}">FlaskTodo</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item active"> <a class="nav-link" href="#">About</a> </li> </ul> </div> </nav> <div class="container"> {% block content %} {% endblock %} </div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> </body> </html>
ファイルを保存して閉じます。
前のブロックのコードのほとんどは、標準のHTMLであり、Bootstrapに必要なコードです。 <meta>
タグはWebブラウザーの情報を提供し、<link>
タグはブートストラップCSSファイルをリンクし、<script>
タグはいくつかの追加のブートストラップ機能を可能にするJavaScriptコードへのリンクです。 詳細については、ブートストラップドキュメントを確認してください。
次に、このbase.html
ファイルを拡張するindex.html
ファイルを作成します。
nano templates/index.html
次のコードをindex.html
に追加します。
フラスコ_todo/templates / index.html
{% extends 'base.html' %} {% block content %} <h1>{% block title %} Welcome to FlaskTodo {% endblock %}</h1> {% for list, items in lists.items() %} <div class="card" style="width: 18rem; margin-bottom: 50px;"> <div class="card-header"> <h3>{{ list }}</h3> </div> <ul class="list-group list-group-flush"> {% for item in items %} <li class="list-group-item">{{ item['content'] }}</li> {% endfor %} </ul> </div> {% endfor %} {% endblock %}
ここでは、for
ループを使用して、lists
ディクショナリの各項目を調べ、リストタイトルを<h3>
タグ内のカードヘッダーとして表示してから、リストを使用します。 <li>
タグのリストに属する各ToDo項目を表示するグループ。 これは、list_example.py
プログラムで説明されているのと同じルールに従います。
ここで、Flaskが必要とする環境変数を設定し、次のコマンドを使用してアプリケーションを実行します。
export FLASK_APP=app export FLASK_ENV=development flask run
開発サーバーが実行されたら、ブラウザでURLhttp://127.0.0.1:5000/
にアクセスできます。 「WelcometoFlaskTodo」とリストアイテムが掲載されたWebページが表示されます。
これで、CTRL + C
と入力して、開発サーバーを停止できます。
ToDoリストと各リストの項目を表示するFlaskアプリケーションを作成しました。 次のステップでは、新しいToDoアイテムを作成するための新しいページを追加します。
ステップ3—新しいToDoアイテムを追加する
このステップでは、To Doアイテムを作成するための新しいルートを作成し、データベーステーブルにデータを挿入し、アイテムをそれらが属するリストに関連付けます。
まず、app.py
ファイルを開きます。
nano app.py
次に、ファイルの最後にcreate()
というビュー関数を使用して新しい/create
ルートを追加します。
フラスコ_todo/app.py
... @app.route('/create/', methods=('GET', 'POST')) def create(): conn = get_db_connection() lists = conn.execute('SELECT title FROM lists;').fetchall() conn.close() return render_template('create.html', lists=lists)
ファイルを保存して閉じます。
このルートを使用してWebフォームを介してデータベースに新しいデータを挿入するため、app.route()
デコレータでmethods=('GET', 'POST')
を使用してGETリクエストとPOSTリクエストの両方を許可します。 create()
ビュー機能では、データベース接続を開き、データベースで使用可能なすべてのリストタイトルを取得し、接続を閉じて、create.html
テンプレートをレンダリングしてリストタイトルを渡します。
次に、create.html
という名前の新しいテンプレートファイルを開きます。
nano templates/create.html
次のHTMLコードをcreate.html
に追加します。
フラスコ_todo/templates / create.html
{% extends 'base.html' %} {% block content %} <h1>{% block title %} Create a New Item {% endblock %}</h1> <form method="post"> <div class="form-group"> <label for="content">Content</label> <input type="text" name="content" placeholder="Todo content" class="form-control" value="{{ request.form['content'] }}"></input> </div> <div class="form-group"> <label for="list">List</label> <select class="form-control" name="list"> {% for list in lists %} {% if list['title'] == request.form['list'] %} <option value="{{ request.form['list'] }}" selected> {{ request.form['list'] }} </option> {% else %} <option value="{{ list['title'] }}"> {{ list['title'] }} </option> {% endif %} {% endfor %} </select> </div> <div class="form-group"> <button type="submit" class="btn btn-primary">Submit</button> </div> </form> {% endblock %}
ファイルを保存して閉じます。
request.form
を使用して、フォームの送信で問題が発生した場合(たとえば、やることコンテンツが提供されなかった場合)に保存されているフォームデータにアクセスします。 <select>
要素では、create()
関数でデータベースから取得したリストをループします。 リストタイトルがrequest.form
に保存されているものと等しい場合、選択されたオプションはそのリストタイトルです。それ以外の場合、リストタイトルは通常の選択されていない<option>
タグで表示されます。
次に、ターミナルで、Flaskアプリケーションを実行します。
flask run
次に、ブラウザでhttp://127.0.0.1:5000/create
にアクセスすると、新しいTo Doアイテムを作成するためのフォームが表示されます。ブラウザから送信されるPOSTリクエストを処理するコードがないため、フォームはまだ機能しないことに注意してください。フォームを送信するとき。
CTRL + C
と入力して、開発サーバーを停止します。
次に、POSTリクエストを処理するためのコードをcreate()
関数に追加し、フォーム関数を正しく作成して、app.py
を開きます。
nano app.py
次に、create()
関数を次のように編集します。
フラスコ_todo/app.py
... @app.route('/create/', methods=('GET', 'POST')) def create(): conn = get_db_connection() if request.method == 'POST': content = request.form['content'] list_title = request.form['list'] if not content: flash('Content is required!') return redirect(url_for('index')) list_id = conn.execute('SELECT id FROM lists WHERE title = (?);', (list_title,)).fetchone()['id'] conn.execute('INSERT INTO items (content, list_id) VALUES (?, ?)', (content, list_id)) conn.commit() conn.close() return redirect(url_for('index')) lists = conn.execute('SELECT title FROM lists;').fetchall() conn.close() return render_template('create.html', lists=lists)
ファイルを保存して閉じます。
request.method == 'POST'
条件内で、フォームデータからToDoアイテムのコンテンツとリストのタイトルを取得します。 コンテンツが送信されなかった場合は、flash()
機能を使用してユーザーにメッセージを送信し、インデックスページにリダイレクトします。 この条件がトリガーされなかった場合は、SELECT
ステートメントを実行して、提供されたリストタイトルからリストIDを取得し、list_id
という変数に保存します。 次に、INSERT INTO
ステートメントを実行して、新しいToDo項目をitems
テーブルに挿入します。 list_id
変数を使用して、アイテムをそれが属するリストにリンクします。 最後に、トランザクションをコミットし、接続を閉じて、インデックスページにリダイレクトします。
最後のステップとして、ナビゲーションバーに/create
へのリンクを追加し、その下に点滅するメッセージを表示します。これを行うには、base.html
を開きます。
nano templates/base.html
create()
表示機能にリンクする新しい<li>
ナビゲーション項目を追加してファイルを編集します。 次に、content
ブロックの上にあるfor
ループを使用して、フラッシュされたメッセージを表示します。 これらはget_flashed_messages()Flask関数で利用できます。
フラスコ_todo/templates / base.html
<nav class="navbar navbar-expand-md navbar-light bg-light"> <a class="navbar-brand" href="{{ url_for('index')}}">FlaskTodo</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item active"> <a class="nav-link" href="{{ url_for('create') }}">New</a> </li> <li class="nav-item active"> <a class="nav-link" href="#">About</a> </li> </ul> </div> </nav> <div class="container"> {% for message in get_flashed_messages() %} <div class="alert alert-danger">{{ message }}</div> {% endfor %} {% block content %} {% endblock %} </div>
ファイルを保存して閉じます。
次に、ターミナルで、Flaskアプリケーションを実行します。
flask run
/create
への新しいリンクがナビゲーションバーに表示されます。 このページに移動して、コンテンツのない新しいTo Doアイテムを追加しようとすると、コンテンツが必要です!というメッセージが点滅します。 コンテンツフォームに入力すると、新しいToDoアイテムがインデックスページに表示されます。
このステップでは、新しいTo Doアイテムを作成し、それらをデータベースに保存する機能を追加しました。
このプロジェクトのソースコードは、このリポジトリにあります。
結論
これで、やることリストとアイテムを管理するためのアプリケーションができました。 各リストには複数のToDo項目があり、各ToDo項目は1対多の関係にある単一のリストに属しています。 FlaskとSQLiteを使用して複数の関連データベーステーブルを管理する方法、外部キーを使用する方法、およびSQLite結合を使用してWebアプリケーションの2つのテーブルから関連データを取得して表示する方法を学習しました。
さらに、groupby()
関数を使用して結果をグループ化し、データベースに新しいデータを挿入し、データベーステーブルの行をそれらが関連するテーブルに関連付けました。 外部キーとデータベースの関係について詳しくは、SQLiteのドキュメントをご覧ください。
PythonFrameworkコンテンツの詳細も読むことができます。 sqlite3
Pythonモジュールを確認したい場合は、 Python3でsqlite3モジュールを使用する方法に関するチュートリアルをお読みください。