想定読者:PythonでWebアプリ開発をやってみたいけど、どうやっていいかさっぱりわからない。PythonとHTMLで作れる機能や作り方が知りたい。初心者向けに細かい解説などもはさんでやってほしい。
こんにちは。だんにこ(@dannikosu)です。
今回はPythonとFlaskを使って、Webアプリ開発をやってみようと思います。初心者向けなので、なるべく解説を入れつつ進めていきます。これからWebアプリ開発をしたい方用に進めさせてもらいますので、実際に手を動かしながら実践してみてください。
僕は業務内ですが、小規模のシステムを1人で作成経験があります。その時はFlask+MySQL+HMTL+CSS+Javascriptを使って作成し、勉強や調べ物をしながらなので3か月くらいかかりました。今回はその経験も生かして、解説していきます。 またPython関連の記事は以下になるので、気になる方はチェックしてみてください。
Webシステムを作りたいけど、どうやっていいかわからない。Pythonはわかったけど、Webシステムのフレームワークがどんなものがあるか知りたい。あとどれがオススメなのかも教えてほしい。 こんにちは。 ... 続きを見る こんにちは。だんにこ(@dannikosu)です。 本記事では、以下のような方向けに記事を書いています。 会社でPythonを使うことになったから勉強しないと…。 副業のため、新しくプロ ... 続きを見る
PythonフレームワークのFlaskとDjangoを比較解説
Windows10でPythonインストール【インストール不要】
※自宅で学習できる0円のプログラミングスクールという近道
エンジニアの僕がおすすめするオンラインでしかも無料で学習できるプログラミングスクールをまとめてみました。独学に限界を感じ始めている方はオンラインプログラミングスクールおすすめですよ。
-
無料:自宅でできるエンジニアおすすめのプログラミングスクール5社
プログラミングスクールに行きたいけど、どんなプログラミングスクールがいいかわからない。料金もどこも高くて払えないよ。なるべく安いところを紹介してほしい。あとコロナで外出できないし、家から自分のペースで ...
続きを見る
Python+Flaskで初めてのWebアプリ開発
テキストエディタのインストールこれから実際にプログラミングを書いていくのですが、プログラムを作成するツールが必要になります。メモ帳でもいいんですが、文字に色が付いたり見やすいほうがプログラミングがはかどると思います。そこで、テキストエディタをインストールするのをお勧めします。テキストエディタもいろいろな種類があって、どれを選んだらいいか迷うと思います。そこで僕が使っているVisual Studio CodeとSublime Textの2つをご紹介します。
Visual Studio Code
https://azure.microsoft.com/ja-jp/products/visual-studio-code/
- マイクロソフト社が開発しているエディタ。
- 誰でも無料で使える。
- WindowsやMac、Linuxなどにも対応。
- 多くのプログラミング言語に対応。
- 拡張機能で好きな機能を追加可能。
上記のような特徴があります。マイクロソフトが開発しているという面で安心感がありますね。ネームバリューがありますから。あとは無料。やはり無料は最強ですからね。ただのものは使っちゃいましょう。 デメリットは少し慣れるまで操作が難しい点があるかもしれません。でも慣れてしまえばメモ帳よりはるかに動作が早くなりますし使いやすいと思います。慣れるまでが一番の頑張り時なので、一緒に乗り越えましょう。
Sublime Text
- 誰でも無料で使える。※ライセンス版もあり
- WindowsやMacで使用可能。
- 動作が非常に軽い。
- 多くのプログラミング言語に対応。
- 拡張機能で好きな機能を追加可能。
- 最初は英語なので日本語化にする必要がある。
Visual Studio Codeに比べて圧倒的に軽い動作が見込めます。あと見た目がシンプルなので、とても使いやすいです。逆を言えば、必要最低限の機能しなかないので、自分でカスタマイズが必要です。あと無料版を使っていると、ライセンス版への誘導ウインドウがたまに出て来ますが、そんなに気にしなくても使用できるレベルです。
僕はSublimeTextを使っています。カスタマイズは少し大変ですが、カスタマイズも終われば、とても扱いやすいテキストエディタです。またこれを機にテキストエディタについても調べてみてください。
初めてのWebアプリ開発
では本題です。これからはWindows10を想定に話を進めていきます。別のOSの方は読み替えてください。まずは初めてのWebアプリということで、PythonとFlaskを使ってWebブラウザに文字列を表示させましょう。
Flaskインストール
まずはコマンドプロンプトで以下を入力してください。
1 |
pip install Flask |
データを保存するフォルダを作成
こちらは任意です。好きなフォルダを作ってもらっても大丈夫です。Cドライブに直接フォルダを作ったほうが必要以外触らないので安全かなと思い、以下のようにしております。フォルダ場所はお任せします。
1 |
c:\web-app\python\flask\ |
フォルダ、ファイル構成
作ったデータ保存場所に以下のようにproject1フォルダの中にhello.pyを作成してください。
1 2 |
project1 └ hello.py |
アプリの構築
hello.pyの中身です。テキストエディタで開いて、以下のように入力してください。
1 2 3 4 5 6 7 8 9 |
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "Hello World" if __name__ == "__main__": app.run(host='127.0.0.1', debug=True, port=8888, threaded=True) |
以下はプログラムの解説になります。
1 |
from flask import Flask |
Flaskをインポートしています。Pythonではインストールしたものはインポートしないと使えないので、忘れずにインポートしましょう。
1 |
app = Flask(__name__) |
Flaskクラスのインスタンスを作って、appという変数に代入しています。変数に入れることで後々でプログラムが簡潔になるためです。
1 |
@app.route('/') |
ルートページの内容を記入していきます。ルートページとは作成するページの一番上位のページです。今回作成するページのaddressはhttp://127.0.0.1:8888/ですが、このページにアクセスしたのがルートページでこの下にどんどんページ内容を追加していきます。
1 2 |
def hello(): return "Hello World" |
ルートページ内に関数を作成しています。単純に文字列を返す関数です。
1 2 |
if __name__ == "__main__": app.run(host='127.0.0.1', debug=True, port=8888, threaded=True) |
- host → 作成するページのアドレスです。
- debug → デバッグモード。オンにするとアクセスしたときに何か不具合があれば表示してくれる機能です。
- port → 作成するページのポート番号です。URLの後ろのほうで使います。
- threaded → 作成したサイトに同時アクセスを可能にするかを指定します。
アプリ起動
作成したアプリをコマンドで立ち上げます。コマンドプロンプト上でデータ保存フォルダに移動して、
1 |
python hello.py |
もしくは、
1 |
py hello.py |
を実行してください。すると、
上記画面で止まりますので、その後サイトにアクセスします。
サイトにアクセス
インターネットブラウザでhttp://127.0.0.1:8888/にアクセス。
結果
上記画面が表示されたら、正常に動作しています。
ちょっとホームページっぽくする。(テンプレートの使用)
次はHTMLファイルと連動させて、ちょっとホームページっぽくします。
Jinja2インストール
テンプレートを使用するには、jinja2のインストールが必要です。
1 |
pip install jinja2 |
フォルダ、ファイル構成
アプリファイル(hello.py)と同じところにtemplatesフォルダを作り、その中にhtmlファイルを入れるのが決まり。フォルダ構成を間違えないでください。
1 2 3 4 5 |
project2 ├ hello.py │ └ templates └ hello.html |
アプリの構築
1 2 3 4 5 6 7 8 9 10 |
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def hello(): return render_template('index.html') if __name__ == "__main__": app.run(debug=True, port=8888, threaded=True) |
以下で部分的に解説をします。
1 |
from flask import Flask, render_template |
render_templateを追加。
1 |
return render_template('index.html') |
render_templateを使って、戻り値をhtmlへ変更。
1 2 3 4 5 6 7 8 9 10 11 |
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>ちょっとホームページっぽくする。</title> </head> <body> <h1>おめでとうございます。</h1> <p>Jinja2でHTMLファイルを読み込みことに成功しました。</p> </body> </html> |
アプリ起動
作成したアプリを以下のコマンドで立ち上げます。前回と同様ですね。
1 |
python hello.py |
サイトにアクセス
http://127.0.0.1:8888/にアクセス。
結果
上記画面のように、htmlファイルの中身が表示されれば、成功です。
テンプレートエンジン Jinja2
Jinja2使い方
先ほど、Jinja2をインストールしましたが、もう少し踏み込んだ使い方をお伝えします。
- {% ... %} → ステートメント。if文やfor文を囲う。
- {{ ... }} → 式や変数などを入れる。
- {# ... #} → コメント。
上記のものを使用することで、HTML上にPythonで定義した変数を使ったり、HTML上でif文やfor文が使用できます。
フォルダ、ファイル構成
1 2 3 4 5 |
project3 ├ hello.py │ └ templates └ hello.html |
前回と同じです。
アプリの構築
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def hello(): title = 'hello.pyからの値渡しのページ' array1 = ['大阪府', '兵庫県', '京都府'] array_2d = [['a', 'b', 'c', 'd'], ['A', 'B']] fruit_dict = {'orange':100, 'apple':200, 'cherry': 400} return render_template('hello.html', title=title, a1=array1, a2=array_2d, f_dict=fruit_dict) if __name__ == "__main__": app.run(debug=False, port=8888, threaded=True) |
以下で部分的に解説をします。
1 2 3 4 |
title = 'hello.pyからの値渡しのページ' array1 = ['大阪府', '兵庫県', '京都府'] array_2d = [['a', 'b', 'c', 'd'], ['A', 'B']] fruit_dict = {'orange':100, 'apple':200, 'cherry': 400} |
Python上にHTMLで使用する変数を定義します。
1 2 |
return render_template('hello.html', title=title, a1=array1, a2=array_2d, f_dict=fruit_dict) |
render_templateの第2引数以降、html用の変数と紐づけします。例えば、a1=array1はa1がHTMLの変数名で、array1はPython用の変数名です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>{{ title }}</title> </head> <body> <h3>配列の単一要素を取り出す </h3> <ul> <li>{{ a1[0] }}</li> </ul> <h3>配列をfor文ですべての要素を取り出す </h3> <ul> {% for i in a1 %} <li>{{ i }}</li> {% endfor %} </ul> <h3>2次元配列をfor文ですべての要素を取り出す </h3> <ul> {% for i in a2 %} {% for j in i %} <li>{{ j }}</li> {% endfor %} {% endfor %} </ul> <h3>2次元配列をfor文ですべての要素を取り出す </h3> <ul> {% for key, value in f_dict.items() %} <li>{{ key }}:{{ value }}</li> {% endfor %} </ul> </body> </html> |
今回のHTMLでは、
- {% ... %} → ステートメント。if文やfor文を囲う。
- {{ ... }} → 式や変数などを入れる。
こちらの使い方の例を表示しています。
1 |
<li>{{ a1[0] }}</li> |
{{ 変数名 }}の形で使用しています。
1 2 3 |
{% for i in a1 %} <li>{{ i }}</li> {% endfor %} |
{% for %}
{{ 変数名 }}
{% endfor %}
の形で使用しています。 for文を使うことで、配列に入っている要素すべて表示が可能です。
アプリ起動
作成したアプリを以下のコマンドで立ち上げる。
1 |
python hello.py |
サイトにアクセス
http://127.0.0.1:8888/にアクセス。
結果
プログラムで使うif文やfor文をHTMLで使用することで、データを全部表示することができます。PythonファイルとHTMLファイルをよく見比べて、どういう流れでデータが移動しているかを確認してみてください。
HTMLを分割できる(レイアウト)
HTMLの最初と最後は他のページでも被る部分があります。重複をなくすために、同じところを一つにまとめようというのが今回の機能です。
フォルダ、ファイル構成
1 2 3 4 5 6 |
├ project4 │ ├ hello.py │ │ │ └ templates │ ├ hello.html(HTML本体) │ └ layout.html (使いまわすHTML) |
アプリ構築
1 2 3 4 5 6 7 8 9 10 11 12 |
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def hello(): name = "who" #return name return render_template('hello.html', title='hello2', name=name) if __name__ == "__main__": app.run(debug=True, port=8888, threaded=True) |
今回のPythonファイルに関しては特に変わったことはしていないので、説明は割愛します。
1 2 3 4 5 |
{% extends "layout.html" %} {% block content %} <h3>Hello</h3> こんにちは。{{ name }}さん。 {% endblock %} |
以下で説明します。
1 |
{% extends "layout.html" %} |
ここでレイアウトファイルを指定します。
1 2 |
{% block content %} {% endblock %} |
これでHTML本体の内容を挟みます。
1 2 3 4 5 6 7 8 9 10 11 |
<!doctype html> <html> <head> <title>{{ title }}</title> </head> <body> {% block content %} <!-- ここに個別のhtmlが入る --> {% endblock %} </body> </html> |
以下で解説です。
1 2 3 |
{% block content %} <!-- ここに個別のhtmlが入る --> {% endblock %} |
上記の通り、layout.htmlでは実際にhello.htmlが入る部分を
1 2 |
{% block content %} {% endblock %} |
これで囲みます。
アプリ起動
作成したアプリを以下のコマンドで立ち上げる。
1 |
python hello.py |
サイトにアクセス
http://127.0.0.1:8888/にアクセス。
結果
HTMLページ追加、画面移動
HTML上でほかのページに移動できるようにしましょう。
フォルダ、ファイル構成
1 2 3 4 5 6 7 |
├ project5 │ ├ hello.py │ │ │ └ templates │ ├ page1.html (1ページ目) │ ├ page2.html (2ページ目) │ └ layout.html (page1とpage2で使いまわすHTML) |
アプリ構築
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def page1(): title = "1ページ目" return render_template('page1.html', title=title) @app.route('/page2') def page2(): title = "2ページ目" return render_template('page2.html', title=title) if __name__ == "__main__": app.run(debug=True, port=8888, threaded=True) |
以下で解説です。
1 2 3 4 |
@app.route('/') def page1(): title = "1ページ目" return render_template('page1.html', title=title) |
1ページ目になります。いわゆるルートページ。アドレスはhttp://127.0.0.1:8888/です。
1 2 3 4 |
@app.route('/page2') def page2(): title = "2ページ目" return render_template('page2.html', title=title) |
2ページ目です。アドレスはhttp://127.0.0.1:8888/page2です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{% extends "layout.html" %} {% block content %} <h3>Good Morning</h3> おはようございます。1ページ目です。 <br> <a href="http://127.0.0.1:8888/page2"> <button type="button">次のページへ</button> </a> {% endblock %} |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{% extends "layout.html" %} {% block content %} <h3>Hello</h3> こんにちは。2ページ目です。 <br> <a href="http://127.0.0.1:8888/"> <button type="button">元のページへ</button> </a> {% endblock %} |
page1とpage2はlayout.htmlを使って作成しています。ページ移動できるようにそれぞれのページにボタンを追加しています。
※layout.htmlは以前と同じです。
アプリ起動
作成したアプリを以下のコマンドで立ち上げる。
1 |
python hello.py |
サイトにアクセス
http://127.0.0.1:8888/にアクセス。
結果
page1
page2
ログイン機能
ログイン機能を追加するために、flask-httpauthをインストールする必要があります。
flask-httpauthをインストール
1 |
pip install flask-httpauth |
フォルダ、ファイル構成
1 2 3 4 5 6 7 8 |
├ project6 │ ├ hello.py │ │ │ └ templates │ ├ layout.html (使いまわし用) │ ├ main.html (ログイン後のページ) │ ├ loginerror.html (ログインエラーページ) │ └ logout.html (ログアウトページ) |
アプリ構築
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
from flask import Flask, render_template from flask_httpauth import HTTPBasicAuth app = Flask(__name__) auth = HTTPBasicAuth() users = { "admin": "password1", "guest": "password2" } @auth.get_password def get_pw(username): if username in users: return users.get(username) return None @app.route('/') @auth.login_required def index(): user = auth.username() return render_template('main.html', title='メインページ', user=user) @auth.error_handler def auth_error(): return render_template('loginerror.html', title='ログインエラー') @app.route('/logout') def logout(): return render_template('logout.html', title='ログアウト'), 401 if __name__ == '__main__': app.run(debug=True, port=8888, threaded=True) |
以下で解説です。
1 |
from flask_httpauth import HTTPBasicAuth |
import文でflask_httpauthを追加します。
1 |
auth = HTTPBasicAuth() |
authインスタンスを作成します。パスワード認証関連のインスタンスです。
1 2 3 4 |
users = { "admin": "password1", "guest": "password2" } |
ユーザーリストとパスワードリストを作成。簡単なデータベースを作成するイメージです。
1 2 3 4 5 |
@auth.get_password def get_pw(username): if username in users: return users.get(username) return None |
パスワードを確認する関数。パスワードを受け取った時に、入力されたユーザーネームがユーザーリストに入っていれば、ユーザーネームを返すという流れです。もし入力されたユーザーがユーザーリストに入っていなければ、何も入っていないNoneを返します。
1 |
@auth.login_required |
パスワードを確認したいページに@auth.login_requiredを追加します。今回はメインページに追加しています。
1 2 3 |
@auth.error_handler def auth_error(): return render_template('loginerror.html', title='ログインエラー') |
ログインエラー時のページ部分です。
1 2 3 |
@app.route('/logout') def logout(): return render_template('logout.html', title='ログアウト'), 401 |
ログアウト時のページ部分です。
※layout.htmlは以前と同じです。
1 2 3 4 5 6 7 8 9 10 11 12 |
{% extends "layout.html" %} {% block content %} <h3>ログインしました。</h3> <p>こんにちは。{{ user }}さん</p> <br> <a href="http://127.0.0.1:8888/logout"> <button type="button">ログアウト</button> </a> {% endblock %} |
1 2 3 4 5 6 7 8 9 10 11 12 |
{% extends "layout.html" %} {% block content %} <h3>ログインエラー</h3> <br> <a href="http://127.0.0.1:8888/"> <button type="button">元のページへ</button> </a> {% endblock %} |
1 2 3 4 5 6 7 8 9 10 11 12 |
{% extends "layout.html" %} {% block content %} <h3>ログアウトしました。</h3> <br> <a href="http://127.0.0.1:8888/"> <button type="button">元のページへ</button> </a> {% endblock %} |
同じくlayout.htmlを使用して、それぞれのページを作成しています。
アプリ起動
作成したアプリを以下のコマンドで立ち上げる。
1 |
python hello.py |
サイトにアクセス
http://127.0.0.1:8888/にアクセス。
結果
ログイン画面
ログイン成功ページ
ログイン失敗ページ
ログアウトページ
まとめ:千里の道も一歩から
初めてのWebアプリ開発どうでしたか。うまく動作しましたか?動作しない場合はよく見比べてみてください。また動作しても、なんでこのプログラムでこのWebページが表示されるのかとかもっと疑問を持ったり、興味を持つことが上達の近道だと思っています。少しずつプログラムというものに興味を持って自分のペースで無理せず進めてみてください。
それでは、また。
※自宅で学習できる0円のプログラミングスクールという近道 プログラミングスクールに行きたいけど、どんなプログラミングスクールがいいかわからない。料金もどこも高くて払えないよ。なるべく安いところを紹介してほしい。あとコロナで外出できないし、家から自分のペースで ... 続きを見る
エンジニアの僕がおすすめするオンラインでしかも無料で学習できるプログラミングスクールをまとめてみました。独学に限界を感じ始めている方はオンラインプログラミングスクールおすすめですよ。
無料:自宅でできるエンジニアおすすめのプログラミングスクール5社