📘

AIを利用して知識ゼロからPythonでシステム構築をする その2 - Flask編 -

2023/09/04に公開

Flask編

前提知識と仕様

  • PHPやJavaを用いたWebアプリケーションの開発経験はあるが、Pythonは全く触った経験無し
  • さくらのレンタルサーバ スタンダードを契約済み
  • 問い合わせは基本的に無料で利用できるChatGPT3.5を利用
  • できる限りAIを利用して構築(使用技術等は自分で決定し、随時記載)
  • フレームワークはFlaskを使ってみることとする

User

Flaskを利用してWebシステムを構築したい。
Flaskの基本的な使い方を教えてください。

ChatGPT

FlaskはPythonで書かれた軽量なWebアプリケーションフレームワークです。以下に、Flaskの基本的な使い方についての概要を説明します。

  1. Flaskのインストール:
    Flaskを使うためには、Pythonのパッケージ管理ツールであるpipを使用してFlaskをインストールする必要があります。ターミナルまたはコマンドプロンプトで以下のコマンドを実行します。

    pip install flask
    
  2. Flaskアプリケーションの作成:
    Pythonのスクリプトファイル内でFlaskアプリケーションを作成します。例えば、app.pyという名前のファイルを作成し、以下のようなコードを書きます。

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello():
        return 'Hello, World!'
    
    if __name__ == '__main__':
        app.run()
    
  3. ルーティング:
    @app.route() デコレータを使用して、アプリケーションのルートURLや他のURLに対するリクエストを処理する関数を定義します。

  4. ビューの作成:
    ルート関数は、リクエストを受け取り、レスポンスを返すビューとして機能します。ビューは、文字列、HTMLテンプレート、JSONなどのレスポンスを返すことができます。

  5. デバッグモードの有効化:
    開発中は、デバッグモードを有効にすると、アプリケーションの変更をリアルタイムで反映させながら開発することができます。以下のコードを追加します。

    if __name__ == '__main__':
        app.run(debug=True)
    
  6. アプリケーションの実行:
    コマンドラインでスクリプトを実行することで、Flaskアプリケーションが起動します。

    python app.py
    

    Flaskはデフォルトで http://127.0.0.1:5000 で動作します。WebブラウザでこのURLにアクセスすると、Hello, World! と表示されます。

これらはFlaskの基本的な使い方の一部です。Flaskにはさまざまな機能があり、テンプレートエンジン、データベース接続、セッション管理などの追加機能を利用することもできます。公式のFlaskドキュメント( https://flask.palletsprojects.com/ )やチュートリアルを参考にして、さらに詳細な使い方を学ぶことをおすすめします。


イマイチのため、もう少し別のプロンプトを考える


User

さくらのレンタルサーバー上にFlaskをinstallしました。
レンタルサーバー上でFlaskを使ったWebシステムを構築するための基礎知識を教えてください。

ChatGPT

Flaskを使ったWebシステムを構築するための基礎知識についてご説明します。以下に、Flaskの基本的な概念や重要な要素について説明します。

  1. Flaskとは:
    FlaskはPythonで書かれた軽量なWebアプリケーションフレームワークです。Web開発において必要な最低限の機能を提供し、柔軟性と拡張性に重点を置いています。

  2. ルート(Routes):
    Flaskでは、URLパスと対応する関数を定義することで、ルートを作成します。これにより、特定のURLにアクセスした際に実行されるコードを定義できます。

  3. ビュー関数(View Functions):
    ビュー関数は、ルートに対応する処理を実装するPythonの関数です。Flaskでは、ビュー関数内で処理を行い、必要なデータを生成してテンプレートに渡すことが一般的です。

  4. URLの変数:
    URLの一部を変数として扱いたい場合、Flaskでは<variable_name>のようにルート定義内で変数を指定できます。ビュー関数内で変数を受け取るには、関数の引数として変数名を指定します。

  5. テンプレート(Templates):
    テンプレートは、HTMLファイル内に変数や条件分岐を埋め込むための仕組みです。Flaskでは、Jinja2というテンプレートエンジンがデフォルトで使用されます。テンプレート内で動的なコンテンツを生成し、ビュー関数から渡されたデータを表示することができます。

  6. 静的ファイル(Static Files):
    静的ファイルは、CSS、JavaScript、画像などの静的なファイルを指します。Flaskでは、静的ファイルを提供するための特別なルートが自動的に作成されます。これにより、Webアプリケーションに静的ファイルを組み込むことができます。

  7. リクエストとレスポンス:
    ユーザーからのリクエストを受け取り、適切なレスポンスを返すことがWebアプリケーションの主な役割です。Flaskでは、リクエストオブジェクトを使用してリクエストデータにアクセスし、レスポンスを生成します。

これらの要素を組み合わせて、Flaskを使ったWebシステムを構築することができます。Flaskの公式ドキュメントやチュートリアルは、詳細な情報と具体的な例を提供してくれるので、開発を進める上で役立つでしょう。順序としては、まずルートを定義し、それに対応するビュー関数を作成し、必要に応じてテンプレートを使用してHTMLページを表示するといった流れで進めていくことが一般的です。


もう少し具体的な例が欲しい


User

Flaskを用いてCRUDのWebアプリを作成したい

ChatGPT

素晴らしいです!Flaskを使用してCRUD(Create, Read, Update, Delete)のWebアプリケーションを作成することは、非常に一般的なタスクです。以下に、基本的な手順を説明します。

  1. Flaskのインストール:
    Flaskを使用するには、まずFlaskパッケージをインストールする必要があります。以下のコマンドを使用して、Pythonパッケージマネージャー(pip)を介してFlaskをインストールできます。

    pip install flask
    
  2. Flaskアプリケーションのセットアップ:
    Flaskアプリケーションを作成するために、Pythonファイルを作成し、必要なモジュールをインポートします。以下は、基本的なFlaskアプリケーションの例です。

    from flask import Flask, render_template, request, redirect
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        # ホームページの表示
        return render_template('index.html')
    
    if __name__ == '__main__':
        app.run(debug=True)
    
  3. ルーティングの設定:
    ルーティングは、URLパスと関数のマッピングを定義するものです。アプリケーション内の各ページに対してルートを設定する必要があります。以下は、例として基本的なルートの設定方法です。

    @app.route('/create', methods=['GET', 'POST'])
    def create():
        # 新しいエントリの作成
        if request.method == 'POST':
            # フォームデータの処理
            # データベースへの保存などの処理
            return redirect('/')
        return render_template('create.html')
    
    @app.route('/edit/<int:id>', methods=['GET', 'POST'])
    def edit(id):
        # エントリの編集
        if request.method == 'POST':
            # フォームデータの処理
            # データベースの更新などの処理
            return redirect('/')
        return render_template('edit.html', id=id)
    
    @app.route('/delete/<int:id>')
    def delete(id):
        # エントリの削除
        # データベースからの削除などの処理
        return redirect('/')
    
  4. テンプレートの作成:
    Flaskでは、テンプレートエンジン(通常はJinja2)を使用してHTMLテンプレートをレンダリングします。テンプレートは、ユーザーに表示されるWebページの外観を定義するために使用されます。以下は、基本的なテンプレートの例です。

    <!-- index.html -->
    <h1>ホームページ</h1>
    <a href="/create">新規作成</a>
    
    <!-- create.html -->
    <h1>新規作成</h1>
    <form method="POST" action="/create">
        <!-- フォームの入力項目 -->
        <input type="submit" value="保存">
    </form>
    
    <!-- edit.html -->
    <h1>編集</h1>
    <form method="POST" action="/edit/{{ id }}">
        <!-- フォームの入力項目 -->
        <input type="submit" value="更新">
    </form>
    
    <!-- その他のテンプレート(必要に応じて作成) -->
    
  5. データベースの統合:
    Flaskはデータベースとの連携に柔軟で、さまざまなデータベースライブラリをサポートしています。好みのデータベースを選んで、Flaskアプリケーションと統合する必要があります。一般的なデータベースライブラリとしては、SQLAlchemyやMongoDBなどがあります。

これらのステップを実行すると、Flaskを使用してCRUDのWebアプリケーションを作成できます。ただし、データベースのセットアップやデータベース操作の詳細な実装は、使用するデータベースによって異なる場合があります。また、セキュリティ上の考慮事項やバリデーションなどの追加機能も考慮する必要があります。


ファイルを作成したがWebで実行ためにはCGIが必要

サーバー構築編で作成したindex.cgiと.htaccessを/test配下にコピー
(.htaccessはRewriteRuleは自ディレクトリに変更)
app.pyは上記のCRUDをマージして作成

実行すると500エラーが発生
AH01215: jinja2.exceptions.TemplateNotFound: index.html: /home/XXX/www/(webroot)/test/index.cgi


User

AH01215: jinja2.exceptions.TemplateNotFound: index.html: となりました。
index.htmlはどこに作ればいいですか?

ChatGPT

Flaskでは、テンプレートファイルを配置するディレクトリ構造が重要です。デフォルトでは、Flaskはアプリケーションのルートディレクトリ内の「templates」という名前のディレクトリをテンプレートの場所として認識します。したがって、index.htmlファイルを作成するには、以下の手順に従ってください。

  1. プロジェクトのルートディレクトリに「templates」という名前のディレクトリを作成します。

  2. 「templates」ディレクトリ内に「index.html」という名前のファイルを作成します。

テンプレートディレクトリの構造は次のようになります。

プロジェクトのルートディレクトリ/
   ├── app.py
   └── templates/
       └── index.html

これにより、Flaskは「templates」ディレクトリをテンプレートの場所として認識し、index.htmlファイルを正しく読み込むことができるはずです。

もしテンプレートディレクトリの場所を変更したい場合は、Flaskアプリケーションのインスタンスを作成する際に、template_folderパラメータを使用してカスタムのテンプレートディレクトリパスを指定することもできます。例えば:

app = Flask(__name__, template_folder='カスタムテンプレートディレクトリパス')

ただし、ディレクトリ構造の変更を行う場合でも、ディレクトリ名は「templates」とし、テンプレートファイルはそのディレクトリ内に配置する必要があります。

問題発生

/test/create を表示すると

    <!-- create.html -->
    <h1>新規作成</h1>
    <form method="POST" action="/create">
        <!-- フォームの入力項目 -->
        <input type="submit" value="保存">
    </form>

が表示されるが保存ボタンをクリックすると
/createにPOSTされるので404が発生


User

/test/create で保存とすると /test/create ではなく /create にPOSTされるので /test/create にPOSTされるようにしたい

ChatGPT

理解しました。Flaskのルーティングで、URLにパラメータを含む場合は、url_forヘルパー関数を使用することで、正しいURLを生成できます。

以下に、url_forを使用してURLを生成する例を示します。

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

@app.route('/')
def index():
    # ホームページの表示
    return render_template('index.html')

@app.route('/test/create', methods=['GET', 'POST'])
def create():
    if request.method == 'POST':
        # フォームデータの処理
        return redirect(url_for('create'))
    return render_template('create.html')

if __name__ == '__main__':
    app.run(debug=True)

上記の例では、create関数内のredirect関数にurl_for('create')を渡しています。これにより、/test/createにPOSTされた後、再び/test/createにリダイレクトされます。

また、url_for関数をテンプレート内で使用することもできます。以下に例を示します。

<!-- create.html -->
<form method="POST" action="{{ url_for('create') }}">
    <!-- フォームの入力項目 -->
    <input type="submit" value="保存">
</form>

このようにすると、テンプレート内でも正しいURLを生成することができます。

このようにして、/test/createにPOSTされるようにすることができます。


うまくいかない

ただ、url_forは有用でcreate.htmlのactionはurl_for('create')で正しいように見える
app.pyでredirect(url_for('create'))としているところにredirect('/')とするとドメイン直下になるのでNGであった。


User

'/' をurl_forで指定する方法は?

ChatGPT

url_for関数でルートURL '/' を指定する方法は、ルート関数名を'index'として渡すことです。Flaskでは、ルートURLが '/' の場合、デフォルトで'index'という名前のルート関数が使用されます。

以下に例を示します。

from flask import Flask, render_template, url_for

app = Flask(__name__)

@app.route('/')
def index():
    # ホームページの表示
    return render_template('index.html')

@app.route('/test/create', methods=['GET', 'POST'])
def create():
    if request.method == 'POST':
        # フォームデータの処理
        return redirect(url_for('index'))
    return render_template('create.html')

if __name__ == '__main__':
    app.run(debug=True)

上記の例では、create関数内のredirect関数にurl_for('index')を渡しています。これにより、'/'にリダイレクトされます。

同様に、テンプレート内でもurl_forを使用できます。

<!-- create.html -->
<form method="POST" action="{{ url_for('index') }}">
    <!-- フォームの入力項目 -->
    <input type="submit" value="ホーム">
</form>

このようにすると、url_for関数を使用して'/'を指定し、対応するURLを生成できます。


これを 元にredirect(url_for('index'))とすると/createでPOSTされたら/にredirectすることに成功
これで実際に画面遷移するところまでは完成

Discussion