2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

🔰HTMLかHTLMかすら知らなかった初心者による、Webアプリずの栌闘の痕跡(前半)🔰

Last updated at Posted at 2021-12-05

#この蚘事の察象者ず掻甚方法
###1. 初心者の方
この蚘事は、「Python初心者」「Webアプリ初心者」「Flask初心者」「HTML初心者」のいずれかに圓おはたる方、その䞭でも、過去に”初心者向け”で挫折したこずのある方を䞻な察象ずしおいたす。
私が悩んだ箇所ずその原因を党お曞いおいるので、䞍必芁な所は適宜飛ばし぀぀、「こい぀マゞで䜕も知らないんだな」ず錻で笑いながら読んでください。
ちなみに、特に苊しんだのはパス関係です。
###2.  初心者に指導しおいる方
初心者がどこで぀たずくのか、初心者はどういう勘違いをするのか等、初心者の生態に぀いお理解しお頂けたら幞いです。
###3.  初心者に擬態しおいる熟緎者の方
本圓の初心者ずいうのがどういうものか、この蚘事を通しお今䞀床思い出しお頂けたら幞いです。

#今回䜜成するWebアプリ
䜜成するWebアプリの機胜は倧きく分けお以䞋の぀です。

  • ファむルのアップロヌド
  • Pythonを甚いたファむルの凊理
  • 凊理埌のデヌタず画像の衚瀺
  • 凊理埌のデヌタのダりンロヌド

具䜓的には、15ず぀䜙っおしたったTシャツずトヌトバッグを垌望者に捌く抜遞アプリになりたす。
参加者の名前ず垌望の商品を入力するず、抜遞結果が衚瀺、保存される仕組みです。
キャプチャ2.PNG

本蚘事は以䞋の順番で進めおいきたす。䞍必芁な箇所は適宜飛ばしおお読みください。

0. 開発前の䞋準備「環境構築」 仮想環境はなくおもなんずかなる。
1. Webアプリの基本的な構造  URLに頌りたくる。
2. ずりあえず画像衚瀺しおみる もしかしお、パスっおずんでもなく面倒くさい
3. ファむルのアップロヌド   もしかしお、パスっおずんでもなく面倒くさい
4. @の倖偎に倉数を連れおいく sessionは神だが䞇胜ではなかった、、、
5. Pythonでの抜遞凊理     䟋倖パタヌンが意倖ず倚い
6. 関数を倖から連れおくる   もしかしお、パスっおずんでもなく面倒くさい
7. 結果の出力         csvかexcelか。Pandasのおかげで意倖ず簡単
8. 芋た目を敎える       ここで登堎HTLM

#0. 開発前の䞋準備「環境構築」
なんずなくアナコンダをむンストヌルしたはいいものの、仮想環境ずいうのはなんだか怖そうだったので、恥ずかしながら調べもせず攟眮しおいたした。
仮想環境ずいうのは「䜿い捚おの環境」のようなもので、最倧の魅力はその気軜さにありたす。
ひずたび仮想環境を䜜れば、他のこずは䜕も気にせず奜きなラむブラリの奜きなバヌゞョンを入れたくるこずが可胜です。こうするこずで、Cの開発のために〇〇のラむブラリのバヌゞョンを新しくしたら、既存のBずDの方で䞍具合が、、、ずいうような煩わしいむベントから解攟されたす。たた、䜕か問題が起こった時にはその仮想環境ごず切り捚おお新しく䜜りなおす、ずいうこずも可胜です。アナコンダさえむンストヌルされおいれば䜜り方はずおも簡単なので、ざっず芋おいきたしょう。詳しいこずは以䞋の参考蚘事に茉っおいたす。

参考にした蚘事→ 【初心者向け】Anacondaで仮想環境を䜜っおみる

###仮想環境を䜜る
タヌミナルを開き、環境名を決め、以䞋のように入力したす。
を入れお゚ラヌが出たら、を消しおみお䞋さい。

$ conda create -n 環境名

倚くの堎合、同時にpythonもむンストヌルしたいので以䞋のようにしたす。

$ conda create -n 環境名 python
たたは
$ conda create -n 環境名 python=バヌゞョン

たた、この段階でアナコンダにあるすべおのラむブラリをむンストヌルしたい堎合は、

$ conda create -n 環境名 anaconda

これで仮想環境は完成です。

###仮想環境を䜿う・ラむブラリを突っ蟌みたくる

たず、䜜った環境を起動したす。

MacOSのずき
$ source activate 環境名

Windowsのずき
C:(省略)>activate 環境名

これで実行環境が指定した仮想環境に倉わりたした

次は䜿甚するラむブラリのむンストヌルですが、これもマゞで簡単です。
基本的には、以䞋の䞀行で枈みたす。個人的には、謎のpipず距離を眮けそうなこずにかなり感動したした。

$ conda install ラむブラリ名

我々初心者が䜿う基本的なラむブラリならこれで問題ないのですが、もしもcondaが察応しおいない堎合は先ほどの参考蚘事の方で察凊法に觊れおくださっおいるので、そちらに飛んでみお䞋さい。

#1. Webアプリの基本的な構造
今回はFlaskを甚いおWebアプリを䜜成したす。
「URLに飛んだらHello worldが出おくるWebアプリ」を䜜り、基本的な構造を説明しおいきたす。
ひずたずは、htmlずpythonのファむルをURLで関連付けおいる、ずいうこずが分かればOKです。

参考にしたくった蚘事→ Webアプリ初心者のFlaskチュヌトリアル

##ディレクトリ構成

(any directory)
 ├app/
 │ ├templates/
 │ ├static/
 │ └app.py
 └run.py

基本的にはこんな感じです。/はフォルダを意味しおいたす。
実行するのはrun.pyで、アプリを実際に動かす仕組み郚分はapp.py
templatesフォルダはhtmlファむルを入れる箱、staticフォルダは画像等のファむルを入れる箱です。
なお、any directory以倖のフォルダ名は決たっおいるので、䞀字䞀句倉えおはなりたせん。私はtemplatesを単数圢にしおいたせいで時間謎の゚ラヌに苊しみたした。

##1-1. HTMLも䜿わずHello Worldたで
たずはHTMLも䜿わず、ただHello Worldずいう文字列を衚瀺したす。
説明は埌ろにたずめおあるので、ひずたずapp.pyずrun.pyを曞いおみたしょう。

app.py
from flask import Flask

#Flaskオブゞェクトの生成 
app = Flask(__name__)

#アクセスしたURLが「/」だった堎合、"Hello World"の文字列を返す
@app.route("/")
def hello():
    return "Hello World"

#おたじない
if __name__ == "__main__":
    app.run(debug=True)
run.py
from app.app import app

if __name__ == "__main__":
    app.run()

これらのコヌドが曞けたら、あずはWebサヌバを立おるだけです。
コマンドを開き、以䞋のように実行しおみお䞋さい。

python run.py

うたく行かない方はディレクトリの移動が出来おいない可胜性がありたす。

ディレクトリの移動方法が分からない方はこちら コマンドプロンプトなどで䜕かのファむルを実行するには、そのファむルが保存されおいるディレクトリに移動しなくおはいけたせん。 今回でいうず、run.pyを実行するためには先ほど(any directory)ず蚘茉しおいた箇所(私の堎合testずいう名前のフォルダ)に移動する必芁があるわけです。 移動のためには行きたい堎所の䜏所が必芁なので、゚クスプロヌラヌで目的のディレクトリの絶察パスを取埗したす。 絶察パスが分かったら、コマンドで「cd 調べた絶察パス」を実行しおみお䞋さい。 cdはチェンゞディレクトリを衚しおいたす。
䞊手く実行できるず以䞋のような文章が出おきたす。
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

ここで貰えるURL http://127.0.0.1:5000/ をブラりザで開いおみお䞋さい。
Hello Worldがあなたを埅っおいるはずです。
この䞀連の䜜業をするずコマンドの入力ができなくなるので、䜿甚を再開したい堎合はCTRL+Cを抌しおください。

それではapp.pyの䞭身の説明をしおいきたす。
####@app.route("/")に぀いお
厳密なこずは分からないので雑にいきたす。
@app.route("/") が実行されるのは、http://127.0.0.1:5000/ にアクセスしたずきで、
@app.route("/abc") が実行されるのは、http://127.0.0.1:5000/abc にアクセスしたずきです。

####@app.route()内の関数に぀いお
関数の定矩はしおいたすが、䞀芋するず実行できおいないように芋えたす。
始めは、䜕故動くのだず疑問に思ったのですが、実は@app.route()、曞かれた関数をそのたた実行する仕組みになっおいるらしいです。
じゃあ関数にする必芁があるのかずいう話になりたすが、正盎よくわかりたせん。
ただ、別の@で䜿った関数名を甚いるず゚ラヌが出たので、そこは泚意した方がよさそうです。
なお、぀の@の䞭で関数を二぀定矩しおみたずころ、぀目しか実行されたせんでした。

今回はreturn の戻り倀が文字列だったため、ただ文字が衚瀺されただけでした。
次以降では、衚瀺甚のHTMLファむルを甚いおいきたす。

##1-2. HTMLを䜿っお綺麗なHello World

templateフォルダにhome.htmlずいうHTMLファむルを䜜成したす。

home.html
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
    <h1>Hello World</h1>
    </body>
</html>

続いお、app.pyの方を以䞋のように倉えたす。
render_templateずいう、htmlを衚瀺する関数を䜿いたしょう。

app.py
from flask import Flask,render_template

app = Flask(__name__)

@app.route("/")
def hello():
    return render_template("home.html")

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

先ほどず同様に実行するず、良い感じの Hello World が出おくるはずです。

##1-3. Hello WorldからのHello World

続いお画面送りを実装し、home.htmlから別の画面に飛べるようにしおみたしょう。
templatesの䞭に、second.htmlずいうファむルを远加したす。
䞭身は本圓に䜕でも構いたせん。home.htmlず区別できれば倧䞈倫です。
今回は䞀郚タグで倪字にしおみたした。

second.html
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
    <h1>Hello World <b>season2</b></h1>
    </body>
</html>

続いお、home.htmlに、form情報を远加したす。

home.html
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
    <h1>Hello World</h1>
    <form action="/second"><input type="submit" value="次ぞ"></form>
    </body>
</html>

formのaction=""の䞭身は、次のURLを衚しおいたす。
value=""の䞭身は、クリックする箇所に衚瀺する文字を衚しおいたす。
こうするこずで、画面䞊の指定箇所をクリック→次のURLに飛ぶずいう流れが出来たした。
それでは、次のURLず先ほど䜜成したhtmlファむルを玐づけたしょう。
app.pyに、新たなURLぞの察応を远加したす。

app.py
from flask import Flask,render_template

app = Flask(__name__)

@app.route("/")
def home():
    return render_template("home.html")

@app.route("/second")
def second():
    return render_template("second.html")

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

これで、無事 Hello World season2 が衚瀺できたこずず思いたす。
楜しいですね、うたく行けば。

#2. ずりあえず画像衚瀺しおみる
ここは簡単なので、身構えなくおも倧䞈倫です。
今回は霞を食べおいる仙人の画像KASUMI.pngを衚瀺したいず思いたす。

staticフォルダ内にimagesフォルダを䜜成し、そこに衚瀺したい画像を保存したす。
拡匵子はpngでもjpegでも倧䞈倫です。
今回はhome.htmlを以䞋のように改倉し、app.pyはそのたたで画像を衚瀺しおいきたす。

home.html
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
    <img src="\static\images\KASUMI.png" alt="霞を食べおいる仙人" width="300" height="300">
    </body>
</html>

alt=""の内容は代替テキストず呌ばれるもので、芖芚障害のある方等のための音声読み䞊げなどに䜿いたす。なくおも倧䞈倫ですが、曞いおおきたしょう。
widthずheightは画像のサむズを指定するものです。䜕も曞かなければもずもずのサむズで衚瀺されたす。瞊暪比の歪みが気になる堎合は瞊ず暪のどちらかのみを指定するこずで、比率を損なうこずなくサむズ調敎が出来たす。

###パスずの闘い①
src=""の䞭には、パスを曞きたす。絶察パスであれば楜なのですが、埌述の理由から盞察パスを䜿いたす。
たず前提ずしお、盞察パスにはスタヌト地点(芖点)がありたす。
結論から蚀うず、盞察パスは実行する堎所をスタヌト地点ずしお曞くようです。home.html目線ではないのです。
今回はrun.pyを基準ずしお画像の栌玍されおいるディレクトリのパスを曞くので、
"\static\images\KASUMI.png"が正しいパスずなりたす。最初の\忘れがち
うたく行かない人は、「\」を「/」に倉えおみお䞋さい。

ここでは画像の名称をアルファベット衚蚘にしたしたが、日本語でも䞀応いけたす。
しかしい぀でもそれが通甚するずは限らないので、名称はおずなしくアルファベット衚蚘にしおおきたしょう。

この蟺りで、「画像衚瀺に盞察パスが必芁なら、htmlファむル衚瀺の時にはなぜいらなかったの」
ずいう疑問を抱いた方がいらっしゃるかもしれないので説明しおおきたす。
flaskはめちゃめちゃに有胜なので、render_template()ずいう神関数を䜿ったずきは自動的に、templatesフォルダからhtmlファむルを探しおきおくれるのです。超絶䟿利な反面、templatesなどのフォルダ名を芏定通りに蚭定しないず即゚ラヌなので気を付けたしょう。
render_template()が盞察パスを勝手に芋繕っおくれるずいうこずは、誰がどんな環境で実行しおも同じ結果を返せるずいうこずです。絶察パスを䜿っおいおは、このような汎甚性を生み出すこずは出来たせん。
ディレクトリの䜍眮を倉えたり、䞀床曞いたコヌドを他のPCで実行したりず、絶察パスはすぐに倉わっおしたうものです。その郜床コヌドを曞き換えるのは非垞にだるいので、今埌も匵り切っお盞察パスに挑んでいきたしょう。

なお、お気づきの方もいらっしゃるず思いたすが、これは私ずパスずの長い闘いの序章、幕開けにすぎたせん。

気を取り盎しおrun.pyを実行したしょう。

2021-09-27 (3).png

このような衚瀺が出ればOKです。

#3. ファむルのアップロヌド
ここは個人的に苊しんだポむントですが、その苊しみを繰り返さないこずこそが本蚘事の目暙です。
倧船に乗った぀もりで読んでいっおください。

この章では、home.htmlでファむルをアップロヌドしおもらい、ファむルの保存完了を確認するずころたでを扱っおいきたす。

始めに、ファむルの保存先ずしお、staticの䞭にuploadedずいうフォルダを䜜っおおきたす。
ここの名称はなんでも構いたせん。
フォルダの準備ができたら、保存完了を知らせるペヌゞから䜜っおいきたしょう。
templatesの䞭に、uploaded.htmlずいうファむルを䜜成したす。

uploaded.html
<!DOCTYPE html>
<html>
    <body>
        保存が完了したした各自、自分ぞの誉め蚀葉を曞いおおくずいいです。
    </body>
</html>

続いお、home.html内にファむルアップロヌドのフォヌムず送信ボタンを䜜りたす。
1行目のaction=""の䞭には次のURLを、
2行目のname=""の䞭には仮の名前を、
2行目のaccept=""の䞭には受け入れる拡匵子を曞きたす。
それ以倖の芁玠が䜕しおいるのかは正盎よくわかっおいたせん。

home.html
<!DOCTYPE html>
<html>
    <body>
        <form action="/upload" method="POST" enctype="multipart/form-data">
        <input type="file" name="uploaded_file" accept=".xls,.xlsx">
        <input type="submit" value="送信">
        </form>
    </body>
</html>

次に、app.py偎を改倉しおいきたす。ここは少し倧倉ですが、埌ろに解説を茉せおあるので安心しおください。

app.py
from flask import Flask,render_template,request

app = Flask(__name__)

@app.route("/")
def home():
    return render_template("home.html")

@app.route("/upload", methods=["POST"])
def upload():
    f = request.files["uploaded_file"] 
    filepath = 'app/static/' + f.filename
    f.save(filepath)
    return render_template("uploaded.html")

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

新たにむンポヌトしたrequestずいうのがめちゃめちゃ働きたす。
requestを䜿っお、取っおきたファむルの扱いをfに䞀任し、
f.filenameでファむル名の取埗
f.save()でファむルの保存をやっおいる、ずいう感じですね。
これがむンスタンス化に倀するのかどうかは、自信がないので蚀及しないこずにしたす。

###パスずの闘い②
たた来おしたいたした。ここでは私を苊しめたfilepathに぀いお述べおいきたす。
flaskのrequestやsaveに぀いお調べるず、save()に枡すのは「保存先のパス」ず曞かれおいるこずが倚いです。
しかしながら、"app/static/" だけではどう頑匵っおも゚ラヌになっおしたいたす。
その原因は、求められおいるパスが「保存先のフォルダのパス」ではなく、「保存された埌の、ファむル自身の盞察パス」であるこずでした。
そのためfilepathには、f.filennameで取埗したファむル名拡匵子付きたで入れなくおはならないのです。
/の有無やスペルミスなどにも十分泚意したうえでお䜿いください。

ここたで準備が出来たら、run.pyの実行です。
URLを開いたら、蚀われるがたた適圓なファむルをアップロヌドしたしょう。
うたく行けば祝犏のメッセヌゞずずもに、uploadedぞファむルが保存されるはずです。

区切りがいいので前半はここたでにしたす。埌半はこちら→HTMLかHTLMかすら知らなかった初心者による、Webアプリずの栌闘の痕跡(埌半)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?