序章

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)そして、このコマンドを使用してアクティブにします。

  1. source env/bin/activate

プログラミング環境がアクティブ化されたら、次のコマンドを使用してFlaskをインストールします。

  1. pip install flask

インストールが完了すると、ToDoデータを格納するために必要なテーブルを作成するためのSQLコマンドを含むデータベーススキーマファイルを作成できるようになります。 2つのテーブルが必要になります:というテーブル lists やることリストを保存し、 items 各リストのアイテムを格納するテーブル。

というファイルを開きます schema.sql あなたの中に flask_todo ディレクトリ:

  1. 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;、これらは、という名前の既存のテーブルを削除します listsitems したがって、紛らわしい動作は見られません。 これにより、これらのSQLコマンドを使用するたびにデータベースにあるすべてのコンテンツが削除されるため、このチュートリアルを終了して最終結果を試すまで、Webアプリケーションに重要なコンテンツを書き込まないようにしてください。

次に、 CREATE TABLE lists を作成するには lists 次の列を持つやることリスト(学習リスト、作業リスト、ホームリストなど)を格納するテーブル:

  • id主キーを表す整数。これには、各エントリのデータベースによって一意の値が割り当てられます(つまり、 やることリスト)。
  • created:やることリストが作成された時刻。 NOT NULL この列が空であってはならず、 DEFAULT 値は CURRENT_TIMESTAMP 値。リストがデータベースに追加された時刻です。 と同じように id、この列の値は自動的に入力されるため、指定する必要はありません。
  • title:リストのタイトル。

次に、というテーブルを作成します items やることアイテムを保存します。 このテーブルにはIDがあります list_id アイテムが属するリスト、作成日、およびアイテムのコンテンツを識別する整数列。 アイテムをデータベース内のリストにリンクするには、外部キー制約を次の行で使用します FOREIGN KEY (list_id) REFERENCES lists (id). ここに lists tableは親テーブルであり、外部キー制約によって参照されているテーブルです。これは、リストに複数の項目を含めることができることを示しています。 The items tableは、制約が適用されるテーブルである子テーブルです。 これは、アイテムが単一のリストに属していることを意味します。 The list_id 列は id の列 lists 親テーブル。

リストには多くのアイテムを含めることができ、アイテムは 1つのリストにのみ属するため、 listsitems テーブルは1対多の関係です。

次に、 schema.sql データベースを作成するファイル。 名前の付いたファイルを開きます init_db.pyflask_todo ディレクトリ:

  1. 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 を作成します listsitems テーブル。 次に、カーソルオブジェクトを使用して、いくつかを実行します INSERT 3つのリストと5つのやること項目を作成するSQLステートメント。

あなたは list_id リストを介して各アイテムをリストにリンクする列 id 価値。 たとえば、 Work リストはデータベースへの最初の挿入だったので、IDがあります 1. これはあなたがリンクする方法です Morning meeting やることアイテム Work-同じルールが他のリストとアイテムに適用されます。

最後に、変更をコミットして接続を閉じます。

プログラムを実行します。

  1. python init_db.py

実行後、という新しいファイル database.db あなたに表示されます flask_todo ディレクトリ。

環境をアクティブ化し、Flaskをインストールし、SQLiteデータベースを作成しました。 次に、データベースからリストとアイテムを取得し、アプリケーションのホームページに表示します。

ステップ2—やること項目の表示

このステップでは、前のステップで作成したデータベースを、やることリストと各リストの項目を表示するFlaskアプリケーションに接続します。 SQLite結合を使用して2つのテーブルからデータをクエリする方法と、ToDo項目をリストごとにグループ化する方法を学習します。

まず、アプリケーションファイルを作成します。 名前の付いたファイルを開きます app.pyflask_todo ディレクトリ:

  1. 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)

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

The 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 アイテムのコンテンツとアイテムが属するリストのタイトルの両方に参加して取得するには、 itemslists テーブル(テーブルエイリアスを使用) i 為に itemsl 為に lists). 結合条件付き i.list_id = l.id 後に ON キーワード、あなたはから各行を取得します items からのすべての行を含むテーブル lists テーブル list_id の列 items テーブルは idlists テーブル。 次に、 ORDER BY リストのタイトルで結果を並べ替えます。

このクエリをよりよく理解するには、 PythonREPLを開きます。 flask_todo ディレクトリ:

  1. python

SQLクエリを理解するには、 todos この小さなプログラムを実行することによって変数:

  1. from app import get_db_connection
  2. conn = get_db_connection()
  3. todos = conn.execute('SELECT i.content, l.title FROM items i JOIN lists l \
  4. ON i.list_id = l.id ORDER BY l.title;').fetchall()
  5. for todo in todos:
  6. print(todo['title'], ':', todo['content'])

最初にインポートします get_db_connection から app.py 次に、ファイルで接続を開き、クエリを実行します(これは、 app.py ファイル)。 の中に for ループすると、リストのタイトルと各ToDo項目の内容が出力されます。

出力は次のようになります。

Output
Home : Buy fruit Home : Cook dinner Study : Learn Flask Study : Learn SQLite Work : Morning meeting

を使用してREPLを閉じます CTRL + D.

SQL結合がどのように機能し、クエリが何を達成するかを理解したので、に戻ってみましょう。 index() あなたのビュー機能 app.py ファイル。 宣言した後 todos 変数の場合、次のコードを使用して結果をグループ化します。

lists = {}

for k, g in groupby(todos, key=lambda t: t['title']):
    lists[k] = list(g)

最初に、という空の辞書を宣言します lists、次に使用する for 結果のグループ化を実行するためのループ todos リストのタイトルによって変数。 からインポートしたgroupby()関数を使用します itertools 標準ライブラリ。 この関数は、の各項目を通過します todos 変数を作成し、キー内の各キーの結果のグループを生成します for ループ。

k リストのタイトルを表します(つまり、 Home, Study, Work)、に渡した関数を使用して抽出されます key のパラメータ groupby() 関数。 この場合、関数は lambda t: t['title'] これは、やること項目を取り、リストのタイトルを返します(以前に行ったように) todo['title'] 前のforループで)。 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 オブジェクトには、から取得したデータが含まれます items でSQLクエリを使用するテーブル index() 関数。 このデータをより適切に表現するために、 lists 辞書を作成し、各リストとそのアイテムを表示します。

というファイルを開きます list_example.py あなたの中で flask_todo ディレクトリ:

  1. 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 プログラム:

  1. python list_example.py

これがの出力です list_example.py:

Output
Home Buy fruit Cook dinner Study Learn Flask Learn SQLite Work Morning meeting

これで、の各部分を理解できました index() 関数、ベーステンプレートを作成し、 index.html 行を使用してレンダリングしたファイル return render_template('index.html', lists=lists).

あなたの中で flask_todo ディレクトリ、作成 templates ディレクトリを開き、というファイルを開きます base.html その中:

  1. mkdir templates
  2. 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に必要なコードです。 The <meta> タグは、Webブラウザの情報を提供します。 <link> タグはブートストラップCSSファイルとリンクします <script> タグは、いくつかの追加のブートストラップ機能を可能にするJavaScriptコードへのリンクです。 詳細については、ブートストラップドキュメントを確認してください。

次に、を作成します index.html これを拡張するファイル base.html ファイル:

  1. 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> タグを付けてから、リストグループを使用して、リストに属する各ToDoアイテムを表示します。 <li> 鬼ごっこ。 これは、 list_example.py プログラム。

ここで、Flaskが必要とする環境変数を設定し、次のコマンドを使用してアプリケーションを実行します。

  1. export FLASK_APP=app
  2. export FLASK_ENV=development
  3. flask run

開発サーバーが実行されたら、URLにアクセスできます http://127.0.0.1:5000/ ブラウザで。 「WelcometoFlaskTodo」とリストアイテムが掲載されたWebページが表示されます。

これで入力できます CTRL + C 開発サーバーを停止します。

ToDoリストと各リストの項目を表示するFlaskアプリケーションを作成しました。 次のステップでは、新しいToDoアイテムを作成するための新しいページを追加します。

ステップ3—新しいToDoアイテムを追加する

このステップでは、To Doアイテムを作成するための新しいルートを作成し、データベーステーブルにデータを挿入し、アイテムをそれらが属するリストに関連付けます。

まず、 app.py ファイル:

  1. 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フォームを介してデータベースに新しいデータを挿入するため、を使用してGETリクエストとPOSTリクエストの両方を許可します。 methods=('GET', 'POST') の中に app.route() デコレータ。 の中に create() ビュー機能では、データベース接続を開き、データベースで使用可能なすべてのリストタイトルを取得し、接続を閉じて、レンダリングします。 create.html リストタイトルを渡すテンプレート。

次に、という新しいテンプレートファイルを開きます create.html:

  1. 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アプリケーションを実行します。

  1. flask run

次に、 http://127.0.0.1:5000/create ブラウザに、新しいTo Doアイテムを作成するためのフォームが表示されます。フォームの送信時にブラウザから送信されるPOSTリクエストを処理するコードがないため、フォームはまだ機能しないことに注意してください。

タイプ CTRL + C 開発サーバーを停止します。

次に、POSTリクエストを処理するためのコードをに追加しましょう create() 機能し、フォームを適切に機能させ、開きます app.py:

  1. 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' フォームデータからやること項目の内容とリストのタイトルを取得する条件。 コンテンツが送信されなかった場合は、を使用してユーザーにメッセージを送信します flash() 機能し、インデックスページにリダイレクトします。 この条件がトリガーされなかった場合は、 SELECT 提供されたリストタイトルからリストIDを取得し、それをという変数に保存するステートメント list_id. 次に、を実行します INSERT INTO 新しいやること項目をに挿入するステートメント items テーブル。 あなたは list_id アイテムをそれが属するリストにリンクする変数。 最後に、トランザクションをコミットし、接続を閉じて、インデックスページにリダイレクトします。

最後のステップとして、次のリンクを追加します /create ナビゲーションバーで、その下に点滅するメッセージを表示します。これを行うには、を開きます base.html:

  1. nano templates/base.html

新しいファイルを追加してファイルを編集します <li> にリンクするナビゲーションアイテム create() ビュー機能。 次に、を使用してフラッシュされたメッセージを表示します for 上記のループ content ブロック。 これらは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アプリケーションを実行します。

  1. flask run

への新しいリンク /create ナビゲーションバーに表示されます。 このページに移動して、コンテンツのない新しいTo Doアイテムを追加しようとすると、コンテンツが必要です!というメッセージが点滅します。 コンテンツフォームに入力すると、新しいToDoアイテムがインデックスページに表示されます。

このステップでは、新しいTo Doアイテムを作成し、それらをデータベースに保存する機能を追加しました。

このプロジェクトのソースコードは、このリポジトリにあります。

結論

これで、やることリストとアイテムを管理するためのアプリケーションができました。 各リストには複数のToDo項目があり、各ToDo項目は1対多の関係にある単一のリストに属しています。 FlaskとSQLiteを使用して複数の関連データベーステーブルを管理する方法、外部キーを使用する方法、およびSQLite結合を使用してWebアプリケーションの2つのテーブルから関連データを取得して表示する方法を学習しました。

さらに、を使用して結果をグループ化しました groupby() 関数、データベースに挿入された新しいデータ、および関連するテーブルに関連付けられたデータベーステーブルの行。 外部キーとデータベースの関係について詳しくは、SQLiteのドキュメントをご覧ください。

PythonFrameworkコンテンツの詳細も読むことができます。 あなたがチェックアウトしたい場合 sqlite3 Pythonモジュールについては、 Python3でsqlite3モジュールを使用する方法に関するチュートリアルをお読みください。