PyCharm 2026.1 Help

Flask を使った Web アプリケーションの作成

このチュートリアルでは、Flask Web フレームワークを使用して Web ベースのアプリケーションを開発する方法について説明します。 MeteoMaster アプリケーションは、データベースに保存されている気象データを処理し、次のグラフの形式で表示します。

  • 散布図—プラハ、サンクトペテルブルク、サンフランシスコ、パリ、シンガポールの年間平均気温と湿度の累積レポート。 サンクトペテルブルク、サンフランシスコ、パリ、シンガポール。

  • 折れ線グラフ — 各都市の月間平均気温と湿度。

「Staying Above the Weather」アプリケーション概要

以下のアプリケーション機能を実装するためにさまざまな Web テクノロジを使用します。

関数

技術

流星データ操作

データを格納するための SQLite(英語) データベース、Python コードでデータベースとの操作を実行するための SQLAlchemy(英語) パッケージ。

グラフ表示

グラフをプロットする matplotlib(英語) パッケージ。

コンテンツの表示と編集

ページビューを作成するための HTML(英語) とスマートテンプレートを作成するための Jinja(英語)

コンテンツを管理する

Flask でアプリケーションコンテンツをまとめます。

MeteoMaster は、次のコンポーネントで構成される Web アプリケーションです。

Flask Web アプリケーションの主要モジュール
メインページ

散布図を表示し、特定の都市の気候の詳細な概要へのリンクを提供するアプリケーションエントリポイント。

都市

各都市の気候に関する詳細情報を含む一連のページ。

ログイン

認証ページ。 気象データを編集するには、有効な資格情報を入力する必要があります。

編集

都市固有のデータを編集するための一連のページ。

各 HTML ページには、Python コードで実装された対応する Flask ビューがあります。

PyCharm で Flask アプリケーションを作成する

Flask プロジェクトの作成 の説明に従って基本的な Flask プロジェクトを作成し、アプリケーションのプロトタイプ作成を開始します。

  1. 新規プロジェクト ダイアログで Flask を選択します。

    新しい Flask プロジェクトの作成
  2. ロケーション 」フィールドにプロジェクトの場所へのパスを入力し、プロジェクト名として 「meteoMaster」と入力します。 残りの設定はデフォルトのままにして、「作成 」をクリックします。

  3. PyCharm は新しい仮想環境を作成し、テンプレート言語として Jinja2 を使用します。 その結果、定義済みのプロジェクト構造と基本的な「Hello World!」コードが提供されます。

    デフォルトの Flask アプリケーション

    上部の 実行 ウィジェットで 実行実行 'meteoMaster' をクリックして、自動的に作成された実行構成を起動します。

  4. 実行 ツールウィンドウでハイパーリンクをクリックし、基本的な「Hello, world」アプリケーションのページをプレビューします。

    Hello World アプリをプレビューする
  5. 次に、MeteoMaster アプリケーションに必要なすべてのパッケージをインストールします。 これを行う最も簡単な方法は、プロジェクト依存関係を使用することです(requirements.txt を使用する を参照)。 プロジェクトルートを右クリックして 新規 | ファイル を選択し、ファイル名として requirements.txt を指定して、次の依存関係のリストをそれに追加します。

    blinker==1.7.0 click==8.1.7 contourpy==1.2.0 cycler==0.12.1 flask==3.0.0 fonttools==4.47.0 itsdangerous==2.1.2 jinja2==3.1.2 kiwisolver==1.4.5 markupsafe==2.1.3 matplotlib==3.8.2 numpy==1.26.2 packaging==23.2 pillow==10.2.0 pyparsing==3.1.1 python-dateutil==2.8.2 six==1.16.0 sqlalchemy==2.0.24 typing-extensions==4.9.0 werkzeug==3.0.1

    パッケージのインストールを続行するには、 requirements のインストール リンクをクリックしてください。

    アプリケーションに必要なパッケージのインストール

データベースのセットアップ

それでは、アプリケーション用のデータソースを設定しましょう。 PyCharm を使えば、とても簡単です。

  1. 次の場所から、5 都市の流星データを含む事前定義データベースをダウンロードします。

    https://github.com/allaredko/flask-tutorial-demo/blob/master/user_database

    user_database ファイルをプロジェクトのルートディレクトリに保存します。

  2. 追加したファイルをダブルクリックします。 開いた データソースおよびドライバー ダイアログで、 接続のテスト をクリックして、データソースが正しく構成されていることを確認します。 不完全な構成 警告が表示された場合は、 ドライバーファイルのダウンロード をクリックします。

    データソースを追加する
  3. OK をクリックしてデータソースの作成を完了すると、 データベースツールウィンドウ が開きます。

    次のテーブルが表示されます。 citymeteo。 各テーブルをダブルクリックしてデータをプレビューします。 city テーブルには city_idcity_namecity_climate (都市の気候に関する簡単な記述)というカラムがあります。 meteo テーブルには city_idmonthaverage_humidityaverage_temperature というカラムがあります。 外部キーtablecity_id カラムに定義されており、2つのテーブル間の関係を設定します。

    流星データベース
  4. Python ファイルを作成する user_database.py 、新しく作成されたデータベースを操作します。 データベースを記述するために SQLAlchemy 宣言ベース(英語)構文を使用してください。

    metadata = MetaData() engine = create_engine('sqlite:///user_database', connect_args={'check_same_thread': False}, echo=False) # echo=False Base = declarative_base() db_session = sessionmaker(bind=engine)() # Table city class City(Base): __tablename__ = 'city' city_id = Column(Integer, primary_key=True) city_name = Column(String) city_climate = Column(String) city_meteo_data = relationship("Meteo", backref="city") # Table meteo class Meteo(Base): __tablename__ = 'meteo' id = Column(Integer, primary_key=True) city_id = Column(ForeignKey('city.city_id')) month = Column(String) average_humidity = Column(Integer) average_temperature = Column(Float)

    コード箇所の import ステートメントを手動で追加する代わりに、提案された クイックフィックスを適用します。バルブ アイコンをクリックするか(または Alt+Enter を押します)。

    欠落しているインポートステートメントに対する迅速な修正の適用
  5. テーブルとそれらの関係を定義したため、データベースからデータを取得するために次の関数を追加します。

    # Retrieving data from the database def get_cities(): return db_session.query(City) # Generating the set of average temperature values for a particular city def get_city_temperature(city): return [month.average_temperature for month in city.city_meteo_data] # Generating the set of average humidity values for a particular city def get_city_humidity(city): return [month.average_humidity for month in city.city_meteo_data] data = get_cities() MONTHS = [record.month for record in data[0].city_meteo_data] CITIES = [city.city_name for city in data]
  6. user_database.py ファイルの完全なコードは以下で入手できます。

    user_database.py
    from sqlalchemy import MetaData, create_engine, Column, Integer, String, ForeignKey, Float from sqlalchemy.orm import declarative_base, sessionmaker, relationship metadata = MetaData() engine = create_engine('sqlite:///user_database', connect_args={'check_same_thread': False}, echo=False) # echo=False Base = declarative_base() db_session = sessionmaker(bind=engine)() # Table city class City(Base): __tablename__ = 'city' city_id = Column(Integer, primary_key=True) city_name = Column(String) city_climate = Column(String) city_meteo_data = relationship("Meteo", backref="city") # Table meteo class Meteo(Base): __tablename__ = 'meteo' id = Column(Integer, primary_key=True) city_id = Column(ForeignKey('city.city_id')) month = Column(String) average_humidity = Column(Integer) average_temperature = Column(Float) # Retrieving data from the database def get_cities(): return db_session.query(City) # Generating the set of average temperature values for a particular city def get_city_temperature(city): return [month.average_temperature for month in city.city_meteo_data] # Generating the set of average humidity values for a particular city def get_city_humidity(city): return [month.average_humidity for month in city.city_meteo_data] data = get_cities() MONTHS = [record.month for record in data[0].city_meteo_data] CITIES = [city.city_name for city in data]

散布図のプロット

データを取得し、各都市の年間平均気温と湿度を示す散布図で最初のグラフをビルドする準備ができました。 グラフをセットアップし値を割り当てるには、 matplotlib ライブラリを使用します。

  1. 別の Python ファイルを作成する charts.py に次のコードを入力します。

    import matplotlib.pyplot as plt from user_database import data, get_city_temperature, get_city_humidity, CITIES yearly_temp = [] yearly_hum = [] for city in data: yearly_temp.append(sum(get_city_temperature(city))/12) yearly_hum.append(sum(get_city_humidity(city))/12) plt.clf() plt.scatter(yearly_hum, yearly_temp, alpha=0.5) plt.title('Yearly Average Temperature/Humidity') plt.xlim(70, 95) plt.ylabel('Yearly Average Temperature') plt.xlabel('Yearly Average Relative Humidity') for i, txt in enumerate(CITIES): plt.annotate(txt, (yearly_hum[i], yearly_temp[i])) plt.show()
  2. グラフをプレビューする最も簡単な方法は、エディター内の任意の場所を右クリックして、コンテキストメニューから 実行 'charts' を選択することです。 PyCharm は プロット ツールウィンドウに散布図を表示します。

    散布図のプレビュー
  3. 次に、アプリケーションのメインページに追加できるように、グラフをイメージに保存します。 plt.show()savefig(img) メソッドを使用するフラグメントに置き換え、コードを get_main_image() 関数にラップします。 取得するものは次のとおりです。

    from io import BytesIO import matplotlib.pyplot as plt from user_database import data, MONTHS, get_city_temperature, get_city_humidity, CITIES def get_main_image(): """Rendering the scatter chart""" yearly_temp = [] yearly_hum = [] for city in data: yearly_temp.append(sum(get_city_temperature(city))/12) yearly_hum.append(sum(get_city_humidity(city))/12) plt.clf() plt.scatter(yearly_hum, yearly_temp, alpha=0.5) plt.title('Yearly Average Temperature/Humidity') plt.xlim(70, 95) plt.ylabel('Yearly Average Temperature') plt.xlabel('Yearly Average Relative Humidity') for i, txt in enumerate(CITIES): plt.annotate(txt, (yearly_hum[i], yearly_temp[i])) img = BytesIO() plt.savefig(img) img.seek(0) return img

メインページの作成

アプリケーションのメインページを設定し、散布図のビューを作成します。

  1. app.py ファイル内の hello_world 関数の定義を app.route() デコレータで次のコードに置き換えます。

    def get_headers(response): response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate' response.headers['Pragma'] = 'no-cache' response.headers['Expires'] = '0' @app.route('/') def main(): """Entry point; the view for the main page""" cities = [(record.city_id, record.city_name) for record in data] return render_template('main.html', cities=cities) @app.route('/main.png') def main_plot(): """The view for rendering the scatter chart""" img = get_main_image() response = send_file(img, mimetype='image/png') get_headers(response) return response
  2. 足りない import 文を追加するために提案された素早い修正を適用してください。

  3. このファイルはまだ作成されていないため、PyCharm は main.html をハイライトしています。

    コード検査

    PyCharm のインテンションアクションを使えば、不足しているテンプレートファイルをすばやく作成できます。 Alt+Enter を押して、コンテキストメニューから テンプレート main.html を作成する を選択します。 テンプレートファイルの名前と場所を確認して、 OK をクリックします。 その結果、 main.html templates ディレクトリに追加されます。 新しく追加したファイルを開き、そのファイルに次のコードを貼り付けます。

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link href="../static/style.css" rel="stylesheet" type="text/css"> <title>Typical Climate</title> </head> <body> <div id="element1"> <img src="{{ url_for('main_plot') }}" alt="Image"> </div> <div id="element2"> <p>What city has the best climate?</p> <p>When planning your trip or vacation you often check weather data for humidity and temperature.</p> <p>Below is the collection of the yearly average values for the following cities: </p> <ul> {% for city_id, city_name in cities %} <li><a href="">{{ city_name }}</a></li> {% endfor %} </ul> </div> </body> </html>

    このフラグメントの {{ city_name }} は、 city_name Python 変数を HTML テンプレートに渡すために使用される Jinja2(英語) テンプレート変数です。

  4. また、スタイルシートを作成して、アプリケーション内のすべての HTML ページのフォントとレイアウトを設定します。 static ディレクトリを右クリックして 新規 | スタイルシート を選択し、 css ファイルの名前 style.css を指定して、次のスタイル定義を貼り付けます。

    body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } #element1 { display: inline-block; } #element2 { display: inline-block; vertical-align: top; margin-top: 90px; alignment: left; width: 25%; }
  5. 自動的に作成された meteoMaster 構成を使用して、結果を評価したいときにいつでも、変更したアプリケーションを実行できます。

    実行実行 または 再実行再実行 をクリックし、 実行 ツールウィンドウの http://127.0.0.1:5000/ リンクに従います。

    実行 / デバッグ構成

    次のページが表示されます:

    MeteoMaster アプリケーションのメインページ

折れ線グラフ

特定の都市の気候に関する詳細情報をアプリケーションユーザーに提供するには、折れ線グラフを関連情報とともにレンダリングします。

  1. get_city_image 関数を追加して charts.py ファイルを修正します。

    def get_city_image(city_id): """Rendering line charts with city specific data""" city = data.get(city_id) city_temp = get_city_temperature(city) city_hum = get_city_humidity(city) plt.clf() plt.plot(MONTHS, city_temp, color='blue', linewidth=2.5, linestyle='-') plt.ylabel('Mean Daily Temperature', color='blue') plt.yticks(color='blue') plt.twinx() plt.plot(MONTHS, city_hum, color='red', linewidth=2.5, linestyle='-') plt.ylabel('Average Relative Humidity', color='red') plt.yticks(color='red') plt.title(city.city_name) img = BytesIO() plt.savefig(img) img.seek(0) return img

    この関数は、各都市の月ごとの 平均日気温平均相対湿度の折れ線グラフをプロットします。 get_main_image 関数と同様に、この関数もグラフを画像として保存します。

  2. 折れ線グラフを表示するために、もう 1 つ .html ファイルを作成します。

    プロジェクトルートの templates ディレクトリを右クリックして 新規 | HTML ファイル を選択し、ファイル名として city.html と入力して、新しく作成したファイルに次のコードを貼り付けます。

  3. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link href="../static/style.css" rel="stylesheet" type="text/css"> <title>{{ city_name }}</title> </head> <body> <div id="element1"> <img src="{{ url_for('city_plot', city_id=city_id) }}" alt="Image"> </div> <div id="element2"> <p>This graph shows mean daily temperature and average relative humidity in {{ city_name }}.</p> <p> {{ city_climate }}</p> <hr/> <p><a href="/">Back to the main page</a></p> </div> </body> </html>
  4. 残りのステップは、 Flask.route 関数を使用してさらに 2 つのビューを作成することです。 app.py ファイルに次のコードを追加します。

    @app.route('/city/<int:city_id>') def city(city_id): """Views for the city details""" city_record = data.get(city_id) return render_template('city.html', city_name=city_record.city_name, city_id=city_id, city_climate=city_record.city_climate) @app.route('/city<int:city_id>.png') def city_plot(city_id): """Views for rendering city specific charts""" img = get_city_image(city_id) response = send_file(img, mimetype='image/png') get_headers(response) return response

    クイックフィックス Alt+Enter を使用して、欠落しているインポートステートメントを追加することを忘れないでください。

  5. main.html ファイルを修正して、都市のリストに対応する シティ /* ページへのリンクを追加します。 <li><a href="">{{ city_name }}</a></li><li><a href="{{ url_for('city', city_id=city_id) }}">{{ city_name }}</a></li> に交換してください。

Run/Debug 設定を再実行してアプリケーションを再起動し、Paris につながるリンクをクリックします。 city/2 ページに移動されることを期待するべきです。

パリの詳細な天気情報

ログインフォームの作成

この時点までに、データベースから隕石データを取得してグラフとして表示する、完全に機能するアプリケーションが作成されています。 ただし、実際には通常、データを編集する必要があります。 当然のことながら、編集は許可されたユーザーにのみ許可されるべきなので、ログインフォームを作成しましょう。

  1. プロジェクトルートの templates ディレクトリを右クリックして 新規 | HTML ファイル を選択し、ファイル名として login.html と入力して、新しく作成したファイルに次のコードを貼り付けます。

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="../static/style.css"> <title>Login form </title> </head> <body> <p>Login to edit the meteo database: </p> <div class="container"> <form action="" class="form-inline" method="post"> <input type="text" class="form-control" placeholder="Username" name="username" value="{{ request.form.username }}"> <input type="password" class="form-control" placeholder="Password" name="password" value="{{ request.form.password }}"> <input class="btn btn-default" type="submit" value="Login"> </form> <p>{{ error }}</p> </div> </body> </html>

    このコードは ユーザー名パスワード フィールドを持つ典型的なログインフォームを実装します。

  2. 次のコードを app.py ファイルに追加して、ログインフォーム用の Flask ビューを作成し、ログインセッションを制御します。

    @app.route('/login/<int:city_id>', methods=["GET", "POST"]) def login(city_id): """The view for the login page""" city_record = data.get(city_id) try: error = '' if request.method == "POST": attempted_username = request.form['username'] attempted_password = request.form['password'] if attempted_username == 'admin' and attempted_password == os.environ['USER_PASSWORD']: session['logged_in'] = True session['username'] = request.form['username'] return redirect(url_for('edit_database', city_id=city_id)) else: print('invalid credentials') error = 'Invalid credentials. Please, try again.' return render_template('login.html', error=error, city_name=city_record.city_name, city_id=city_id) except Exception as e: return render_template('login.html', error=str(e), city_name=city_record.city_name, city_id=city_id) def login_required(f): @wraps(f) def wrap(*args, **kwargs): """login session""" if 'logged_in' in session: return f(*args, **kwargs) else: pass return redirect(url_for('login')) return wrap app.secret_key = os.environ['FLASK_WEB_APP_KEY']

    不足しているインポートステートメントを追加するには、 Alt+Enter ショートカットを使用します。 このコードでは、 USER_PASSWORDFLASK_WEB_APP_KEY という 2 つの環境変数が導入されています。

  3. 新しく作成した環境変数の値は、より安全にセキュリティ機密情報を保管する方法として、 meteoMaster 実行/デバッグ構成に記録できます。これは app.py ファイルにハードコーディングするよりも安全です。

    実行 ウィジェットで をクリックし、 実行構成の編集 を選択します。 実行 / デバッグ構成 ダイアログで、 meteoMaster 構成が選択されていることを確認し、 環境変数 フィールドの Edit environmental variables アイコンをクリックして 2 つの変数を追加します。

    環境変数を追加する
  4. ログイン機能に対応するように city.html ファイルの <div id="element2"> 要素を変更します。

    <p>This graph shows mean daily temperature and average relative humidity in {{ city_name }}.</p> <p> {{ city_climate }}</p> {% if session['logged_in'] %} <p>Want to add more data?</p> <p>Go and <a href="{{ url_for('edit_database', city_id=city_id) }}">edit</a> the meteo database.</p> {% else %} <p>Want to edit meteo data?</p> <p>Please <a href="{{ url_for('login', city_id=city_id) }}">login</a> first.</p> {% endif %} <hr/> <p><a href="/">Back to the main page</a></p>
  5. アプリケーションを再起動し、都市のリンクをクリックしてから、「最初にログインしてください」という文の中の ログイン リンクをクリックします。 ログインフォームが表示されるはずです。

    ログインフォーム

    当面は、対応するページを実装していないため、このフォームでは編集できません。 一方、誤ったパスワードを入力して「無効な認証情報です。 もう一度やり直してください」というメッセージで処理されているかどうかを確認することもできます。

データを編集する

最後の残りのステップは流星データの編集を可能にすることです。

  1. プロジェクトルートの templates ディレクトリを右クリックして 新規 | HTML ファイル を選択し、ファイル名として edit.html と入力して、新しく作成したファイルに次のコードを貼り付けます。

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="../static/style.css"> <title>Edit meteo data for {{ city_name }}</title> </head> <body> <p>Edit the data for {{ city_name }} as appropriate:</p> <div class="container"> <form name="meteoInput" action="" class="form-inline" method="post"> <table> <tr> <td>Month</td> <td colspan="2" align="center">Average Temperature</td> <td colspan="2" align="center">Average Humidity</td> </tr> {% for month in months %} <tr> <td>{{ month }}</td> <td> <input placeholder="20" class="form-control" name="temperature{{ loop.index0 }}" value="{{ meteo[0][loop.index0]}}" type="range" min="-50.0" max="50.0" step="0.01" oninput="temp_output{{ loop.index0 }}.value=this.value" > </td> <td> <output name="temp_output{{ loop.index0 }}">{{ '%0.2f' % meteo[0][loop.index0]|float }}</output> <label> C</label> </td> <td> <input placeholder="20" class="form-control" name="humidity{{ loop.index0 }}" value="{{ meteo[1][loop.index0]}}" type="range" min="0" max="100" oninput="hum_output{{ loop.index0 }}.value=this.value"> </td> <td> <output name="hum_output{{ loop.index0 }}">{{ meteo[1][loop.index0]}}</output> <label> %</label> </td> </tr> {% endfor %} </table> <input class="btn btn-default" type="submit" value="Save"> </form> <p>{{ error }}</p> </div> </body> </html>

    このフラグメントはまた、Jinjia2 テンプレートを利用して入力データを処理し、それをデータベースへのコミットを実行する Python コードに渡します。

  2. 編集ページ用の Flask ビューを作成し、入力データを処理し、データベースを更新する app.py ファイルに、もう 1 つコードフラグメントを追加します。

    @app.route('/edit/<int:city_id>', methods=["GET", "POST"]) @login_required def edit_database(city_id): """Views for editing city specific data""" month_temperature = [] month_humidity = [] city_record = data.get(city_id) meteo = [get_city_temperature(city_record), get_city_humidity(city_record)] try: if request.method == "POST": # Get data from the form for i in range(12): # In a production application we ought to validate the input data month_temperature.append(float(request.form[f'temperature{i}'])) month_humidity.append(int(request.form[f'humidity{i}'])) # Database update for i, month in enumerate(city_record.city_meteo_data): month.average_temperature = month_temperature[i] month.average_humidity = month_humidity[i] db_session.commit() return redirect(url_for('main', city_id=city_id)) else: return render_template('edit.html', city_name=city_record.city_name, city_id=city_id, months=MONTHS, meteo=meteo) except Exception as error: return render_template('edit.html', city_name=city_record.city_name, city_id=city_id, months=MONTHS, meteo=meteo, error=error)

    app.py ファイルの完全なコードは以下で入手できます。

    app.py
    import os from functools import wraps from flask import Flask, send_file, render_template, request, session, redirect, url_for from charts import get_main_image, get_city_image from user_database import data, db_session, get_city_temperature, get_city_humidity, MONTHS app = Flask(__name__) def get_headers(response): response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate' response.headers['Pragma'] = 'no-cache' response.headers['Expires'] = '0' @app.route('/') def main(): """Entry point; the view for the main page""" cities = [(record.city_id, record.city_name) for record in data] return render_template('main.html', cities=cities) @app.route('/main.png') def main_plot(): """The view for rendering the scatter chart""" img = get_main_image() response = send_file(img, mimetype='image/png') get_headers(response) return response @app.route('/city/<int:city_id>') def city(city_id): """Views for the city details""" city_record = data.get(city_id) return render_template('city.html', city_name=city_record.city_name, city_id=city_id, city_climate=city_record.city_climate) @app.route('/city<int:city_id>.png') def city_plot(city_id): """Views for rendering city specific charts""" img = get_city_image(city_id) response = send_file(img, mimetype='image/png') get_headers(response) return response @app.route('/login/<int:city_id>', methods=["GET", "POST"]) def login(city_id): """The view for the login page""" city_record = data.get(city_id) try: error = '' if request.method == "POST": attempted_username = request.form['username'] attempted_password = request.form['password'] if attempted_username == 'admin' and attempted_password == os.environ['USER_PASSWORD']: session['logged_in'] = True session['username'] = request.form['username'] return redirect(url_for('edit_database', city_id=city_id)) else: print('invalid credentials') error = 'Invalid credentials. Please, try again.' return render_template('login.html', error=error, city_name=city_record.city_name, city_id=city_id) except Exception as e: return render_template('login.html', error=str(e), city_name=city_record.city_name, city_id=city_id) def login_required(f): @wraps(f) def wrap(*args, **kwargs): """login session""" if 'logged_in' in session: return f(*args, **kwargs) else: pass return redirect(url_for('login')) return wrap app.secret_key = os.environ['FLASK_WEB_APP_KEY'] @app.route('/edit/<int:city_id>', methods=["GET", "POST"]) @login_required def edit_database(city_id): """Views for editing city specific data""" month_temperature = [] month_humidity = [] city_record = data.get(city_id) meteo = [get_city_temperature(city_record), get_city_humidity(city_record)] try: if request.method == "POST": # Get data from the form for i in range(12): # In a production application we ought to validate the input data month_temperature.append(float(request.form[f'temperature{i}'])) month_humidity.append(int(request.form[f'humidity{i}'])) # Database update for i, month in enumerate(city_record.city_meteo_data): month.average_temperature = month_temperature[i] month.average_humidity = month_humidity[i] db_session.commit() return redirect(url_for('main', city_id=city_id)) else: return render_template('edit.html', city_name=city_record.city_name, city_id=city_id, months=MONTHS, meteo=meteo) except Exception as error: return render_template('edit.html', city_name=city_record.city_name, city_id=city_id, months=MONTHS, meteo=meteo, error=error) if __name__ == '__main__': app.run()
  3. 実行構成を再起動するか、 app.py ファイル (Ctrl+S) を保存して自動再起動をトリガーします。 これで、アプリのホームページでたとえば Paris を選択し、 編集 をクリックして管理者の資格情報を入力すると、流星データを編集できるページが表示されます。

    流星パラメーターの編集

このステップで、データベースとやり取りする Flask ベースのアプリケーションを作成するタスクが完了しました。 これで、天気を完全に制御できるようになりました。 任意の都市の気象データを変更して、変更がグラフ上で目立つようにします。 次に、変更をプレビューします。

2026 年 6 月 1 日