著者はCOVID-19救済基金を選択し、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

Flask はPythonを使用してWebアプリケーションを構築するためのフレームワークであり、SQLiteはPythonでアプリケーションデータを保存するために使用できるデータベースエンジンです。

このチュートリアルでは、 URL短縮サービスを構築します。これは、任意のURLを受け取り、bit.lyのような短くて読みやすいバージョンを生成するサービスです。

Hashids は、整数から短い一意のIDを生成するライブラリです。 たとえば、12のような数値を1XcIdのような一意の文字列に変換するために使用できます。 Hashidsを使用して、URLIDの一意の文字列を生成します。

一意の文字列を使用して、動画共有サイトの動画のIDを生成したり、画像をアップロードするサービスの画像のIDを生成したりできます。 この一意の文字列は、予測できないIDを提供します。 したがって、ユーザーがyour_domain/image/J32Frの画像にアクセスできる場合、他の画像の場所を予測することはできません。 URL短縮サービスで整数IDを使用する場合、これは不可能です。たとえば、your_domain/image/33を使用すると、ユーザーは他の画像の場所を予測できます。 予測できないURLは、ユーザーが他のユーザーによって短縮された別のURLを処理することを妨げるため、サービスにプライバシーの形式を追加します。

Flask、SQLite、および Hashids ライブラリを使用して、URL短縮サービスを構築します。 アプリケーションでは、ユーザーがURLを入力して短いバージョンを生成できるほか、ユーザーがURLがクリックされた回数を表示できる統計ページを使用できます。 Bootstrapツールキットを使用してアプリケーションのスタイルを設定します。

前提条件

  • ローカルPython3プログラミング環境については、 Python3シリーズのローカルプログラミング環境をインストールおよびセットアップする方法のチュートリアルに従ってください。 このチュートリアルでは、プロジェクトディレクトリをflask_shortenerと呼びます。

  • ルートの作成、HTMLテンプレートのレンダリング、SQLiteデータベースへの接続などの基本的なFlaskの概念の理解。 これらの概念に精通していない場合は、 Python3でFlaskを使用してWebアプリケーションを作成する方法とPython3でsqlite3モジュールを使用する方法を確認してください。

ステップ1—依存関係を設定する

このステップでは、Python環境をアクティブ化し、pipパッケージインストーラーを使用してFlaskとHashidsライブラリをインストールします。 次に、URLの保存に使用するデータベースを作成します。

まず、プログラミング環境をまだアクティブにしていない場合はアクティブにします。

  1. source env/bin/activate

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

  1. pip install flask hashids

次に、urlsテーブルを作成するためのSQLコマンドを含むschema.sqlというデータベーススキーマファイルを作成します。 flask_shortenerディレクトリ内にあるschema.sqlというファイルを開きます。

  1. nano schema.sql

このファイル内に次のSQLコマンドを入力します。

フラスコショートナー/スキーマ.sql
DROP TABLE IF EXISTS urls;

CREATE TABLE urls (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    original_url TEXT NOT NULL,
    clicks INTEGER NOT NULL DEFAULT 0
);

スキーマファイルで、urlsテーブルがすでに存在する場合は、最初に削除します。 これにより、urlsという名前の別のテーブルが存在する可能性が回避され、混乱を招く動作が発生する可能性があります。 たとえば、列が異なる場合です。 これにより、スキーマファイルが実行されるたびに既存のデータがすべて削除されることに注意してください。

次に、次の列を使用してテーブルを作成します。

  • id:URLのID。これは各URLエントリの一意の整数値になります。 これを使用して、ハッシュ文字列から元のURLを取得します。
  • created:URLが短縮された日付。
  • original_url:ユーザーをリダイレクトする元の長いURL。
  • clicks:URLがクリックされた回数。 初期値は0で、リダイレクトごとに増加します。

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

schema.sqlファイルを実行してurlsテーブルを作成するには、flask_shortenerディレクトリ内にinit_db.pyという名前のファイルを開きます。

  1. nano init_db.py

次に、次のコードを追加します。

フラスコ_shortener/init_db.py
import sqlite3

connection = sqlite3.connect('database.db')

with open('schema.sql') as f:
    connection.executescript(f.read())

connection.commit()
connection.close()

ここでは、このプログラムを実行するとプログラムが作成するdatabase.dbというファイルに接続します。 このファイルは、アプリケーションのすべてのデータを保持するデータベースです。 次に、schema.sqlファイルを開き、複数のSQLステートメントを同時に実行する executescript()メソッドを使用して実行します。 これにより、urlsテーブルが作成されます。 最後に、変更をコミットして接続を閉じます。

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

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

  1. python init_db.py

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

これで、FlaskとHashidsライブラリをインストールし、データベーススキーマを作成し、urlsというテーブルを使用してSQLiteデータベースを作成し、URL短縮サービスの元のURLを保存しました。 次に、Flaskを使用して、ユーザーがURLを入力して短縮URLを生成できるインデックスページを作成します。

ステップ2—URLを短縮するためのインデックスページを作成する

このステップでは、インデックスページのFlaskルートを作成します。これにより、ユーザーはURLを入力して、データベースに保存できます。 ルートはURLのIDを使用して、Hashidsライブラリで短縮文字列ハッシュを生成し、短縮URLを作成して、結果としてレンダリングします。

まず、flask_shortenerディレクトリ内のapp.pyという名前のファイルを開きます。 これはメインのFlaskアプリケーションファイルです。

  1. nano app.py

次のコードをファイルに追加します。

フラスコ_shortener/app.py
import sqlite3
from hashids import Hashids
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

このコードでは、最初にsqlite3モジュール、hashidsライブラリからのHashidsクラス、およびFlaskヘルパーをインポートします。

get_db_connection()関数は、database.dbデータベースファイルへの接続を開き、row_factory属性をsqlite3.Rowに設定します。 その結果、名前に基づいて列にアクセスできます。 データベース接続は、通常のPythonディクショナリのように動作する行を返します。 最後に、この関数は、データベースへのアクセスに使用するconn接続オブジェクトを返します。

次に、以下を追加します。

フラスコ_shortener/app.py
. . .
app = Flask(__name__)
app.config['SECRET_KEY'] = 'this should be a secret random string'

hashids = Hashids(min_length=4, salt=app.config['SECRET_KEY'])

Flaskアプリケーションオブジェクトを作成し、秘密鍵をセキュアセッションに設定します。 秘密鍵は秘密のランダムな文字列であるため、Hashidsライブラリのsaltを指定するためにも使用します。 これにより、塩が変化するたびにハッシュも変化するため、ハッシュが予測できないことが保証されます。

注:ソルトは、ハッシュ関数(つまり、hashids.encode())に提供されるランダムな文字列であり、結果のハッシュはソルトに基づいてシャッフルされます。 このプロセスにより、取得するハッシュがソルトに固有であることが保証されるため、ハッシュのエンコードとデコードに使用できるのは自分だけの秘密のパスワードのように、ハッシュは一意で予測不可能です。 セキュリティ上の理由から、秘密にしておくことを忘れないでください(これが、アプリケーションの秘密鍵を使用する理由です)。

min_lengthパラメーターに値を渡すことにより、ハッシュが少なくとも4文字の長さであることを指定するhashidsオブジェクトを作成します。 アプリケーションの秘密鍵をソルトとして使用します。

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

フラスコ_shortener/app.py
. . .
@app.route('/', methods=('GET', 'POST'))
def index():
    conn = get_db_connection()

    if request.method == 'POST':
        url = request.form['url']

        if not url:
            flash('The URL is required!')
            return redirect(url_for('index'))

        url_data = conn.execute('INSERT INTO urls (original_url) VALUES (?)',
                                (url,))
        conn.commit()
        conn.close()

        url_id = url_data.lastrowid
        hashid = hashids.encode(url_id)
        short_url = request.host_url + hashid

        return render_template('index.html', short_url=short_url)

    return render_template('index.html')

index()関数はFlaskview関数で、特別な@app.routeデコレータを使用して装飾された関数です。 その戻り値は、WebブラウザなどのHTTPクライアントが表示するHTTP応答に変換されます。

index()ビュー関数内で、methods=('GET', 'POST')app.route()デコレータに渡すことにより、GET要求とPOST要求の両方を受け入れます。 データベース接続を開きます。

次に、要求がGET要求の場合、最後の行までif request.method == 'POST'条件をスキップします。 ここで、index.htmlというテンプレートをレンダリングします。このテンプレートには、ユーザーが短縮するURLを入力するためのフォームが含まれています。

リクエストがPOSTリクエストの場合、if request.method == 'POST'条件はtrueです。これは、ユーザーがURLを送信したことを意味します。 URLはurl変数に保存します。 ユーザーが空のフォームを送信した場合は、メッセージThe URL is required!をフラッシュして、インデックスページにリダイレクトします。

ユーザーがURLを送信した場合は、INSERT INTO SQLステートメントを使用して、送信されたURLをurlsテーブルに格納します。 ?プレースホルダーをexecute()メソッドに含め、送信されたURLを含むタプルを渡して、データベースにデータを安全に挿入します。 次に、トランザクションをコミットして接続を閉じます。

url_idという変数に、データベースに挿入したURLのIDを格納します。 lastrowid 属性を使用して、URLのIDにアクセスできます。この属性は、最後に挿入された行の行IDを提供します。

hashids.encode()メソッドを使用してハッシュを作成し、URLIDを渡します。 結果をhashidという変数に保存します。 たとえば、hashids.encode(1)を呼び出すと、使用するソルトによってはKJ34のような一意のハッシュが生成される場合があります。

次に、request.host_urlを使用して短縮URLを作成します。これは、FlaskのrequestオブジェクトがアプリケーションのホストのURLにアクセスするために提供する属性です。 これは、開発環境ではhttp://127.0.0.1:5000/になり、アプリケーションをデプロイする場合はyour_domainになります。 たとえば、short_url変数は、http://127.0.0.1:5000/KJ34のような値になります。これは、ハッシュKJ34

最後に、index.htmlテンプレートをレンダリングして、short_url変数を渡します。

すべての追加後、ファイルは次のようになります。

フラスコ_shortener/app.py
import sqlite3
from hashids import Hashids
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'

hashids = Hashids(min_length=4, salt=app.config['SECRET_KEY'])


@app.route('/', methods=('GET', 'POST'))
def index():
    conn = get_db_connection()

    if request.method == 'POST':
        url = request.form['url']

        if not url:
            flash('The URL is required!')
            return redirect(url_for('index'))

        url_data = conn.execute('INSERT INTO urls (original_url) VALUES (?)',
                                (url,))
        conn.commit()
        conn.close()

        url_id = url_data.lastrowid
        hashid = hashids.encode(url_id)
        short_url = request.host_url + hashid

        return render_template('index.html', short_url=short_url)

    return render_template('index.html')

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

次に、ベーステンプレートとindex.htmlテンプレートファイルを作成します。

flask_shortenerディレクトリに、templatesディレクトリを作成し、その中にbase.htmlというファイルを開きます。

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

base.html内に次のコードを追加します。 スタイリングには、ここでもBootstrapを使用していることに注意してください。 FlaskのHTMLテンプレートに慣れていない場合は、 Python3でFlaskを使用してWebアプリケーションを作成する方法のステップ3を参照してください。

フラスコ_shortener/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')}}">FlaskShortener</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">
        {% for message in get_flashed_messages() %}
            <div class="alert alert-danger">{{ message }}</div>
        {% endfor %}
        {% 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コードへのリンクです。 詳細については、ブートストラップドキュメントを確認してください。

<title>{% block title %} {% endblock %}</title>タグを使用すると、継承するテンプレートでカスタムタイトルを定義できます。 for message in get_flashed_messages()ループを使用して、フラッシュされたメッセージ(警告、アラートなど)を表示します。 {% block content %} {% endblock %}プレースホルダーは、継承するテンプレートがコンテンツを配置する場所であり、すべてのテンプレートがこの基本テンプレートにアクセスできるようにします。これにより、繰り返しが回避されます。

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

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

  1. nano templates/index.html

次のコードを追加します。

フラスコ_shortener/templates / index.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskShortener {% endblock %}</h1>
    <form method="post">
    <div class="form-group">
        <label for="url">URL</label>
        <input type="text" name="url"
               placeholder="URL to shorten" class="form-control"
               value="{{ request.form['url'] }}" autofocus></input>
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
    </form>

    {% if short_url %}
    <hr>
    <span>{{ short_url }}</span>
    {% endif %}
{% endblock %}

ここでは、base.htmlを拡張し、タイトルを定義し、urlという名前の入力を使用してフォームを作成します。 url入力により、ユーザーは短縮するURLを入力できます。 値はrequest.form['url']で、送信に失敗した場合にデータを保存します。 つまり、ユーザーがURLを提供しない場合です。 送信ボタンも追加します。

次に、short_url変数に値があるかどうかを確認します。これは、フォームが送信され、短縮URLが正常に生成された場合に当てはまります。 条件が真の場合、フォームの下に短縮URLを表示します。

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

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

FLASK_APP環境変数は、実行するアプリケーション(app.pyファイル)を指定します。 FLASK_ENV環境変数はモードを指定します。 developmentは、デバッガーが実行されている状態でアプリケーションが開発モードで実行されることを意味します。 本番環境でこのモードを使用することは避けてください。 flask runコマンドを使用してアプリケーションを実行します。

ブラウザを開き、URLhttp://127.0.0.1:5000/を入力します。 Welcome toFlaskShortenerページがあります。

Flask Shortener Index page

URLを送信すると、短縮URLが届きます。

Flask Shortened URL displayed beneath the URL input box

URLを受け入れて短いページを生成するページを使用してFlaskアプリケーションを作成しましたが、URLはまだ何もしていません。 次のステップでは、短縮URLからハッシュを抽出し、元のURLを見つけて、ユーザーをそのURLにリダイレクトするルートを追加します。

ステップ3—リダイレクトルートを追加する

このステップでは、アプリケーションが生成する短いハッシュを取得し、ハッシュを元のURLのIDである整数値にデコードする新しいルートを追加します。 新しいルートも整数IDを使用して、元のURLを取得し、clicks値をインクリメントします。 最後に、ユーザーを元のURLにリダイレクトします。

まず、app.pyを開いて、新しいルートを追加します。

  1. nano app.py

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

フラスコ_shortener/app.py
. . .

@app.route('/<id>')
def url_redirect(id):
    conn = get_db_connection()

    original_id = hashids.decode(id)
    if original_id:
        original_id = original_id[0]
        url_data = conn.execute('SELECT original_url, clicks FROM urls'
                                ' WHERE id = (?)', (original_id,)
                                ).fetchone()
        original_url = url_data['original_url']
        clicks = url_data['clicks']

        conn.execute('UPDATE urls SET clicks = ? WHERE id = ?',
                     (clicks+1, original_id))

        conn.commit()
        conn.close()
        return redirect(original_url)
    else:
        flash('Invalid URL')
        return redirect(url_for('index'))

この新しいルートは、URLを介して値idを受け入れ、それをurl_redirect()ビュー関数に渡します。 たとえば、http://127.0.0.1:5000/KJ34にアクセスすると、文字列'KJ34'idパラメータに渡されます。

ビュー関数内で、最初にデータベース接続を開きます。 次に、hashidsオブジェクトのdecode()メソッドを使用して、ハッシュを元の整数値に変換し、original_id変数に格納します。 original_idに値があることを確認します。これは、ハッシュのデコードが成功したことを意味します。 値がある場合は、そこからIDを抽出します。 decode()メソッドはタプルを返すため、元のIDであるoriginal_id[0]を使用してタプルの最初の値をフェッチします。

次に、SELECT SQLステートメントを使用して、元のURLとそのクリック数をurlsテーブルからフェッチします。URLのIDは、ハッシュから抽出した元のIDと一致します。 fetchone()メソッドを使用してURLデータをフェッチします。 次に、データを2つのoriginal_url変数とclicks変数に抽出します。

次に、UPDATE SQLステートメントを使用して、URLのクリック数をインクリメントします。

トランザクションをコミットして接続を閉じ、redirect()Flaskヘルパー関数を使用して元のURLにリダイレクトします。

ハッシュのデコードに失敗した場合は、URLが無効であることをユーザーに通知するメッセージをフラッシュし、インデックスページにリダイレクトします。

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

開発サーバーを実行します。

  1. flask run

ブラウザを使用してhttp://127.0.0.1:5000/に移動します。 URLを入力し、結果の短縮URLにアクセスします。 アプリケーションは元のURLにリダイレクトします。

ユーザーを短縮URLから元のURLにリダイレクトする新しいルートを作成しました。 次に、各URLにアクセスした回数を示すページを追加します。

ステップ4—統計ページを追加する

このステップでは、各URLがクリックされた回数を表示する統計ページの新しいルートを追加します。 また、ナビゲーションバーのページにリンクするボタンを追加します。

短縮された各リンクが受けた訪問数をユーザーが確認できるようにすることで、各URLの人気を可視化できます。これは、マーケティング広告キャンペーンなどのプロジェクトに役立ちます。 このワークフローは、既存のFlaskアプリケーションに機能を追加する例として使用することもできます。

app.pyを開いて、統計ページの新しいルートを追加します。

  1. nano app.py

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

フラスコ_shortener/app.py
. . .

@app.route('/stats')
def stats():
    conn = get_db_connection()
    db_urls = conn.execute('SELECT id, created, original_url, clicks FROM urls'
                           ).fetchall()
    conn.close()

    urls = []
    for url in db_urls:
        url = dict(url)
        url['short_url'] = request.host_url + hashids.encode(url['id'])
        urls.append(url)

    return render_template('stats.html', urls=urls)

このビュー機能では、データベース接続を開きます。 次に、urlsテーブルのすべてのエントリのID、作成日、元のURL、およびクリック数を取得します。 fetchall()メソッドを使用して、すべての行のリストを取得します。 次に、このデータをdb_urls変数に保存し、接続を閉じます。

各エントリの短縮URLを表示するには、それを作成し、データベースからフェッチしたURLのリスト(db_urls)の各アイテムに追加する必要があります。 urlsという空のリストを作成し、db_urlsリストをfor url in db_urlsでループします。

dict() Python関数を使用して、sqlite3.Rowオブジェクトを辞書に変換し、割り当てを許可します。 short_urlという新しいキーを、値request.host_url + hashids.encode(url['id'])でディクショナリに追加します。これは、インデックスビュー関数で短いURLを作成するために以前に使用したものです。 この辞書をurlsリストに追加します。

最後に、stats.htmlというテンプレートファイルをレンダリングし、urlsリストを渡します。

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

次に、新しいstats.htmlテンプレートファイルを作成します。

  1. nano templates/stats.html

次のコードを入力します。

フラスコ_shortener/templates / stats.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} FlaskShortener Statistics {% endblock %}</h1>
    <table class="table">
        <thead>
            <tr>
            <th scope="col">#</th>
            <th scope="col">Short</th>
            <th scope="col">Original</th>
            <th scope="col">Clicks</th>
            <th scope="col">Creation Date</th>
            </tr>
        </thead>
        <tbody>
            {% for url in urls %}
                <tr>
                    <th scope="row">{{ url['id'] }}</th>
                    <td>{{ url['short_url'] }}</td>
                    <td>{{ url['original_url'] }}</td>
                    <td>{{ url['clicks'] }}</td>
                    <td>{{ url['created'] }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>

{% endblock %}

ここでは、タイトルを指定し、次の列でテーブルを定義することにより、base.htmlベーステンプレートを拡張します。

  • #:URLのID。
  • Short:短縮URL。
  • Original:元のURL。
  • Clicks:短縮URLにアクセスした回数。
  • Creation Date:短縮URLの作成日。

各行は、urlsリストを通過し、各URLの各列の値を表示するforループを使用して入力されます。

次のコマンドで開発サーバーを実行します。

  1. flask run

ブラウザを使用してhttp://127.0.0.1:5000/statsに移動します。 テーブルにすべてのURLがあります。

Statistics page with list of URLs and number of clicks

次に、ナビゲーションバーにStatsボタンを追加します。 base.htmlファイルを開きます。

  1. nano templates/base.html

次の強調表示された行に従ってファイルを編集します。

フラスコ_shortener/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>

            <li class="nav-item active">
                <a class="nav-link" href="{{ url_for('stats')}}">Stats</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>

    <!-- 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>

ここでは、新しい<li>アイテムをナビゲーションバーに組み込みます。 url_for()機能を使用して、stats()ビュー機能にリンクします。 これで、ナビゲーションバーから統計ページにアクセスできます。

統計ページには、短いURLやアクセス回数など、各URLに関する情報が表示されます。

このコードを再利用して、ソーシャルメディアサイトで投稿が高く評価または更新された回数や、写真/ビデオが表示された回数を追跡するなど、他のコンテキストでのクリック数を監視できます。

このリポジトリからアプリケーションの完全なコードにアクセスできます。

結論

ユーザーが長いURLを入力し、短いバージョンを生成できるようにするFlaskアプリケーションを作成しました。 整数を短い文字列ハッシュに変換し、ユーザーをあるリンクから別のリンクにリダイレクトし、短縮URLを監視できるように統計用のページを設定しました。 Flaskの操作に関するその他のプロジェクトとチュートリアルについては、次のチュートリアルを確認してください。