flaskによるWebアプリ開発⑤~url_forと変数による動的URLの作成方法

前回までのあらすじ

【Python】初心者向けの「Flask」に使った簡単なWebサイトの作り方①

flaskによるWebアプリ開発②~テンプレートエンジン(Jinja2)を使って動的Webページを作る

flaskによるWebアプリ開発③~GETとPOSTとformタグでのデータの送受信

flaskによるWebアプリ開発④~SQLAlchemyを使ってデータベースと連動させる

今回は少し高度なURLルーティング、つまり変数を使った動的なURLの作成方法について解説していきます。

ルーティングとは何か?

Flaskの使い方を色々書いていて今さらにはなりますが、改めてルーティングについて解説するとWebアプリケーションにおけるルーティングとは、URLと処理を紐づけすることです

flaskアプリケーションは、関数とURLを紐付けることで、ユーザからアクセスできるようになっています。flaskのルーティングは、<code>.route() </code>で定義されます。これまでなんとなくコピペしていたであろう「@app.route()」はルーティングを定義しています。

from flask import Flask
app = Flask(__name__)

@app.route(‘/’) # http://xxx 以降のURLパスを ‘/’ と指定
def index():
return ‘hello world!!’

上記の例では、 http://xxx/ と index() を紐付けています。http://xxx/ にアクセスすると、「Index Page」とだけ書かれた質素なページが表示されます。これがもっともシンプルなルーティングです。

・静的ファイルのルーティング

webサイトに必要なのはテキストだけではありません。現在のWebサイトのようなオシャレなものを作る場合はタグの装飾を凝ったり画像や動きを付ける必要があります。

なので、もし個人のお遊びではなく、実務などでまともなWebサイトを作ろうとなるとhtml以外に、画像ファイルである「.png」や、htmlをオシャレにできるcss、htmlに動きを付けるJavascriptを扱う必要があります。

CSSやJavaScript、画像といった静的ファイルのルーティングは自動でされます。デフォルトでは、 http://xxx/static が static ディレクトリに対応しています。htmlを保管している「templates」と同じように、Flaskのアプリケーションファイル内に 「static」 という名前のディレクトリを作成すると自動的にルーティングされます。]

前述したような route() による定義は必要ありません。フォルダのディレクトリ構成は↓のようなイメージになっています。

<pre>

FlaskApp

└──app.py

└──templates

└──index.html
└── static
├── css
│ └── test.css
├── js
│ └── test.js
└──img

└──test.png

</pre>

static以下のディレクトリは、ディレクトリ名がパスとしてルーティングされます。上記構成の場合、以下のURLが有効です。

http://xxx/static/img/test.png
http://xxx/static/css/test.css
http://xxx/static/js/test.js

httpメソッドまたはif文での条件分岐ルーティング

<code>route()</code> は、引数の<code>methods=</code>の部分にHTTPメソッド名のリストを渡してやることで、そのURLが受け入れるHTTPメソッドを指定できます。何も指定しない場合のデフォルトは<code> methods=[‘GET’, ‘POST’]</code>で両方とも受け付けます。

例えばユーザが入力フォームに書いた内容を送信する処理などは、 methods=[‘POST’]にすることで、POST以外のメソッドを使ったアクセスはじくことができ、セキュリティ対策になります。またメソッドに応じて条件分岐させることも可能です。

<pre>

@app.route(‘/’, methods=[‘GET’, ‘POST’])
def edit():
# 共通の処理
if request.method == ‘get’:
# GET時の処理
else:
# POST時の処理
# 共通の処理

</pre>

HTTPメソッドの指定を変えることで、同じURLでも異なる関数へとルーティングできます。

<pre>

@app.route(‘/edit’, methods=[‘GET’])
def get_edit():
# GET時の処理

@app.route(‘/edit’, methods=[‘POST’])
def post_edit():
# POST時の処理

</pre>

methods に値を指定することで、HTTPメソッドを指定できます。例では、GETとPOSTのリクエストをルーティングしています。

処理の内容にもよりますが、GETとPOSTで異なる処理をすることがほとんどであり、ifで分岐させるよりも、関数を呼び出す時点で分岐しておいた方がコードが見やすくなるので個人的にはそうやって書くことが多いです。HTTPメソッドごとに関数を定義する場合は、関数名をget_〇〇、post_〇〇のようにしておくとわかりやすいです。

まあこのcssや条件分岐辺りはコードを見ればなんとなくで理解できるので、今まであまり触れていませんでしたが、Webアプリケーションを構築する上で少し難しいのが「変数による動的なルーティング」をするケースです。

「変数による動的URLなルーティング」の顕著な例としてはログイン制のサイトがあります。ログインしてブラウザの上部を見てもらえれば分かりますが、ユーザー名ごとに自動でURLが作成され、会員ごとに別々のページが表示されています。

この「変数による動的URLルーティング」は僕がflaskを勉強した時にハマったところなので、今回ここで1つ記事にして解説しようと思った次第です。

変数による動的なURLルーティング

たとえば、会員登録して使うサイトなどではUser ID=1のデータをリクエストと一緒に送信したいという場合があります。その場合、値をURLの一部として渡す、もしくは、クエリとして渡すのが一般的です。

<app.py>

from flask import Flask, request, render_template
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
@app.route(“/members”)
def user_url():
lists=[[1,‘太郎’],[2,‘次郎’],[3,‘三郎’]]
return render_template(“member.html”,lists=lists)
@app.route(“/member_detail/<int:id>/<name>”,)
def detail(id,name):
lists=[[‘太郎’,24,‘サッカー’],[‘次郎’,45,‘野球’],[‘三郎’,67,‘バスケ’]]
index=id1
data=lists[index]
return render_template(“detail.html”,data=data,name=name)

<menber.html>

<!DOCTYPE html>
<html lang=“ja”>
<head>
<body>
<p></p>
<table>
 
  <tr>
  <th>社員ID</th>
<th>社員名</th>
 
 
</tr>
  <tbody>
{% block body %}
  {% for d in lists %}
  <tr>
  <td>{{ d[0] }}</td>
<td>{{ d[1] }}</td>
<td>
<a href=“{{ url_for(‘detail’,id=d[0],name=d[1]) }}”>詳細</a>
</td>
 
</tr>
   
  {% endfor %}
  </tbody>
  </table>
 
  {% endblock %}
   
 <p></p>
</body>
</html>

<detail.html>

<html>
<p></p>
<h3>{{ name }}の社員情報です。</h3>
<p></p>
<table>
 
  <tr>
  <th>年齢</th>
<th>趣味</th>
 
 
</tr>
  <tbody>
  <tr>
  <td>{{ data[1] }}歳</td>
<td>{{ data[2] }}</td>
 
</tr>
   
  </tbody>
  </table>
 
 
<p></p>
</html>

前者のように http://xxx/edit/1 のようにデータをurlに渡したいという場合は、変数付きのルーティングを用います。flaskではURLの後にカッコ有りの記述を入れることで、URLと一緒についてきたものを拾えます。

@app.route(“/member_detail/<int:id>/<name>”,)の部分ではidとnameを拾っています。int:と付け足すことでidの中身はint型以外受け付けないと指定しています。

データ型が特に指定されていない場合、stringとして扱われます。converterに指定した型と異なる型のデータがURLとして渡された場合、 404 NotFound を返します。

型 説明
string (デフォルト) /(半角スラッシュ)以外の全ての文字を受け付けます。
int 正の整数を受け付けます。
float 正の実数を整数または、小数を受け付けます。
path スラッシュを含む全ての文字を受け付けます。
uuid UUID文字列を受け付けます。

そしてhtml上に既に別のルーティングで渡されている情報を別のURLに移動する際にくっつけておきたい場合はurl_forを用います。url_forの引数の指定方法は<code>url_for(‘送信先の関数名’,送信するデータ)</code>です。

こんかいは送信先の関数としてdetail()を指定しているため、それと紐づいている@app.route(“/member_detail/<int:id>/<name>”,)にアクセスするURLを生成します。

今回の動的URLには変数部分にidとnameが設定されているため、キーワード引数としてidとnameに送るデータを指定します。

今回送信されているのはd[0]とd[1]の中身です。そして、送信先のdetail()関数の引数にidとnameが指定してあるので、送ったデータをそのまま使うことができ、それを利用して対応したユーザーの年齢と趣味の情報をdetail.htmlに渡しているという流れになります。

また、変数にはデフォルト値を設定できます。ひとつの関数に対して、複数のURLを紐づけることもできます。この2つを組み合わせると、以下のようなルーティングも可能です。

@app.route(‘/list’)
@app.route(‘/list/<int:page>’)
def get_list(page=1):
# <int:page> が未指定の場合、page=1が設定される

終わり

以上がFlaskにおけるurl_forを使用した動的なURLの作成方法です。動的なURLはログイン認証サイトなんかを作る際には欠かせないのでぜひ使えるようにしておきましょう。

プログラミングの独学はとても難しい


プログラミングは小学校の義務教育にも導入され始めており、これから社会人として生きていく上でプログラミングはもはや出来て当たり前、出来なれば論外というエクセルレベルの必須スキルになりつつあります。そしてそういう話を聞いて参考書なりを購入して独学でプログラミング勉強しようと思っている人も少なくないでしょう。しかしプログラミングを独学で勉強し始めようと思うものの



・「分からない箇所で詰まって挫折してしまった」

・「勉強する時間が足りない」

・「ネットの記事だと情報が断片的でよくわからない」

・「コードのエラーの原因が分からない」



という壁にぶち当たって、プログラミングの勉強を止めてしまう方が少なくありません。独学でプログラミングを勉強してる時間のほとんどはつまづいている時間です。実際僕も最初のころ独学でプログラミングを勉強していた頃はエラーの原因が分からず丸1日を不意にしてしまった・・・そんな苦い経験がありました。



それで僕は一度はプログラミングの学習を諦めてしまいましたが、就活で現実を知る中で「プログラミングを勉強して、いずれフリーランスとして自由な生き方がしたい」「エンジニアとして若いうちから高収入を得たい」という気持ちから一念発起して「侍エンジニアのwebサービスコース」に申し込み、プロのエンジニアの方に対面でマンツーマンでPythonによるWebサービス作り方とWeb技術の基本を教えてもらい、ようやくプログラミングが理解でき、今ではエンジニアとしてそこそこの暮らしができるようになりました。





侍エンジニアでは、とりあえずプログラミングやインターネットの基本を知っておきたい人から、HTML・cssなどでWebサイトやWebアプリを作ってみたい人やPythonを勉強してデータサイエンティストやAIエンジニアになりたい人まで幅広いニーズに応えた様々なコースが用意されています。



IT業界と言ってもエンジニアの仕事はプログラミング言語次第でサーバーから機械学習・ディープラーニングまで多種多様ですし、侍エンジニアの無料レッスン(カウンセリング)を受けてみて、自分のやりたいITの仕事は何なのか?を見つけるのがエンジニアへの第一歩になります。ちなみに今侍エンジニアの無料レッスンを受けると1000円分のAmazonギフト券がもらえるので、試しに受けてみるだけもお得です。


自分は半端に独学やオンラインスクールで勉強して金と時間を無駄にするくらいなら、リアルのプログラミングスクールに通ってしっかりプログラミングを勉強した方がいいと思います。ちなみに今、侍エンジニアに申し込むと、25歳以下の学生の方であれば、受講料が20%OFFになるので超お得です。


そして、プログラミングは大勢で授業を受けたり漫然とオンライン学習をするよりも自分が分からない箇所をピンポイントでプロの講師に直接質問して、ちゃんと納得するというスタイルの方がお金は確かに少し掛かりますが、独学で学ぶよりも絶対にモノになります。


シェアする

  • このエントリーをはてなブックマークに追加

フォローする