こんばんわ。Flaskの勉強第二話です。第一話はこっちらでみてだくさい↓
Pathのものを渡してみよう
user.html
<h1>Hello,{{name}}</h1>
main.py
from flask import Flask, render_template
app=Flask(__name__)
app.debug=True
@app.route("/")
def hello():
return render_template("index.html")
@app.route("/page1")
def page1():
return render_template("page1.html")
@app.route('/user/<name>')
def user(name):
return render_template("user.html",name=name)
if __name__ =="__main__":
app.run()
python3 app.py
結果はこんな感じです:

もしlocalhost:5000/user/test1を入れるとHello,test1が出てきます。

もしlocalhost:5000/user/test2を入れるとHello,test1が出てきます。

サーバー側の反応からみえると…
ではどうやって?
<h1>Hello,{{name}}</h1>
htmlをみてください。{{name}}はつまり{{ }}の中のものは外からもらってる意味です。
@app.route('/user/<name>')
def user(name):
return render_template("user.html",name=name)
<name>はつまりuser/*** 、このpathの***を変数として扱います。
templateをReturnしname=nameと一緒に渡しします。
そしてこのnameをuser.htmlの中にあるname変数に渡しします。
Bootstrap Frameworkを使ってみようか?
まずbootstrapをInstallします。
pip install Bootstrap
main.py
#Using Bootstrap flamework
from flask_bootstrap import Bootstrap
from flask import Flask, render_template
app=Flask(__name__)
app.debug=True
bootstrap=Bootstrap(app)
@app.route("/")
def hello():
return render_template("index.html")
@app.route("/page1")
def page1():
return render_template("page1.html")
@app.route('/user1/<name>')
def user1(name):
return render_template("user1.html",name=name)
if __name__ =="__main__":
app.run()
user1.html
{% extends "bootstrap/base.html" %}
{% block title%}Title{% endblock %}
{% block navbar%}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigration</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Flasky</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a hef="/">Home</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>hello,{{name}}!</h1>
</div>
</div>
{% endblock %}
{% block scripts %}
{{ super() }}
<script type="text/javascript" src="{{ url_for('static',filename='script.js')}}"></script>
{% endblock %}
python3 main.py

同じな結果が出ました。が、なぜCSSが勝手に変わった?bootstrapのFlameworkを使ってたのせいでhtmlでbootstrapに対応するid,classを定義すればCSSを書かずに済みます。

サーバーから見ると…
ではどうやって?
main.py
from flask_bootstrap import Bootstrap
まずはもちろんモジュールImportしないといけない。
bootstrap=Bootstrap(app)
アプリケーションをBootstrapに嵌める、サーバー側はOK。
user1.html
{% extends "bootstrap/base.html" %}
bootstrapにはbase.htmlをextendsします。文字とおりです。
次はHTMLの要素にbootstrapが対応するIDとClassをはめるのでここは詳しく説明しません。
{% block scripts %}
{{ super() }}
<script type="text/javascript" src="{{ url_for('static',filename='script.js')}}"></script>
{% endblock %}
ちょっとメモしたいのはここですね。自分が書いてたのJSデータを嵌めたいの場合はまず{{super()}}を先に書かないといけません。そのあとはstaticの中にあるscript.jsを嵌めてください!の意味です。
404、501などのエラーPAGEも自分で作ろう
今回はbootstrapのFrameworkを使わなで、w3.cssというFrameworkを使います。↓
main.py
from flask import Flask, render_template
app=Flask(__name__)
app.debug=True
@app.route("/")
def hello():
return render_template("index.html")
@app.route("/page1")
def page1():
return render_template("page1.html")
@app.route('/user2/<name>')
def user2(name):
return render_template("user2.html",name=name)
@app.errorhandler(404)
def page_not_found(errorDescp):
return render_template("404.html",errorDescp=errorDescp),404
@app.errorhandler(500)
def inter_server_error(errorDescp):
return render_template("500.html",errorDescp=errorDescp),500
if __name__ =="__main__":
app.run()
404.html
{% extends "base.html "%}
{% block title%}404isNotFound...{% endblock%}
{% block content %}
<div class="w3-red">
<h2 class="w3-text-white">Page is Not Found.</h2>
<h2>{{ errorDescp }}</h2>
</div>
{% endblock %}
{% block footer %}
{% endblock %}
base.html
<title>{% block title%} {{ setting.SETTING}} {% endblock %}</title>
{% block style %}
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
{% endblock %}
{% block navbar %}
<div class="w3-bar w3-black">
<a href="#" class="w3-bar-item w3-button w3-mobile">Home</a>
<a href="#" class="w3-bar-item w3-button w3-mobile">Link 1</a>
<a href="#" class="w3-bar-item w3-button w3-mobile">Link 2</a>
<a href="#" class="w3-bar-item w3-button w3-mobile">Link 3</a>
</div>
{% endblock %}
{% block content %}
{% endblock %}
{% block footer%}
{% endblock %}
python3 main.py
ちょっとScreenshot忘れたけど…
ではどうやって?
@app.errorhandler(404)
def page_not_found(errorDescp):
return render_template("404.html",errorDescp=errorDescp),404
@app.errorhandler(500)
def inter_server_error(errorDescp):
return render_template("500.html",errorDescp=errorDescp),500
Flaskはプログラマーが自分でErrorページを作ることができて、例えばよくある404、500など。今回の例は404.htmlしかありませんが、@app.errorhandler(404)は404のエラーが出たとき処理してくれるのです。(errorDescp)は当時のエラーメッセージを取り、最後はTemplate404.htmlを呼び出して404を渡しします。
{% extends "base.html "%}
{% block title%}404isNotFound...{% endblock%}
base.htmlからextendsします…今回は自分で簡単なbaseを作ってやってみようと思います。
{% block title%}404isNotFound…{%endblock%}はtitleの文字を設定します。
{% block style %}
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
{% endblock %}
Stylesheetを設定します。
<title>{% block title%} {{ setting.SETTING}} {% endblock %}</title>
{% block style %}
{{ setting.SETTING}}で外から渡されたのParametersここで使うことができるんですね。stackoverflowでちょっとした説明があります↓
https://stackoverflow.com/questions/12339324/jinja2-default-page-title
Formを使う
pip install flask-wtf
flask-wtfの使います。まずInstallしましょう。Flask-WTF extensionはFlasksでformsをもっと色々な機能できるようになるのです。DefaultではFlask-WTFが全てのformsを Cross-Site Request Forgery (CSRF)から保護されてます。つまり悪意があるReqとか、違うWEBからLoginしたりとか。詳しくの説明はここ↓
StepとしてはまずSECRET_KEYを設定→form classを作成→最後は処理って感じですね。Flask-WTFはこのKEYを使って暗号化したりformsからきたのReqを認証したり。SECRET_KEYはapp.configで設定することができます。
これはFlask-WTFで使えるのformです。↓

これはFlask-WTFで使えるのvalidatorsです。↓

main.py
from flask import Flask, render_template
from flask_wtf import Form
from wtforms import StringField,SubmitField
from wtforms.validators import Required
class NameForm(Form):
name=StringField('Value1:',validators=[Required()])
submit=SubmitField('Submit')
app=Flask(__name__)
app.debug=True
app.config['SECRET_KEY']='something key'
@app.route('/',methods=['GET','POST'])
def index():
name=None
form=NameForm()
if form.validate_on_submit():
name=form.name.data
form.name.data=''
return render_template('index5.html',form=form,name=form.name.data)
if __name__ =="__main__":
app.run()
index5.html
{% extends "base.html"%}
{% block title%}Send Somethings{% endblock%}
{% block content %}
<div class='w3-panel w3-yellow'>
<h1>Hello,Please input something</h1>
<h2>What you input:{%if name %}{{name}}{% else %}Nothings{% endif %}</h2>
</div>
<form method="POST">
{{ form.name.label}}{{form.name()}}
{{ form.submit()}}
</form>
{% endblock%}
python main.py

サーバー側:

ではどうやって?
from flask_wtf import Form from wtforms import StringField,SubmitField from wtforms.validators import Required
まずは使用するモジュールをIMPORTします。
class NameForm(Form):
name=StringField('Value1:',validators=[Required()])
submit=SubmitField('Submit')
NameFormのClassを作ります。LabelはValue1で、Required()はEmptyの内容は受け付けませんってこと。最後はもちろんSubmitのButtonも作ります。
app.config['SECRET_KEY']='something key'
SECRET_KEYを作ります。
@app.route('/',methods=['GET','POST'])
def index():
name=None
form=NameForm()
if form.validate_on_submit():
name=form.name.data
form.name.data=''
return render_template('index5.html',form=form,name=form.name.data)
もし’/’のpathでGet/Postが発生したらこのFunctionが走りますね。form.validate_on_submit()はsubmitされた内容が正しいかどうかを判断してくれます。前のRequired()覚えてます?つまりいまはEmptyじゃなければTrueになります
<h2>What you input:{%if name %}{{name}}{% else %}Nothings{% endif %}</h2>
もしNameが空っぽじゃなければ、Nameの内容を出力します。そうではないときはNothingsを出力する簡単な論理処理です。
F5を押したときなにか変と思わないか?

これはBrowserがまえ処理してるのReqまだ覚えてるのせいです。今回はこれも消してみましょう。
main.py
from flask import Flask, render_template,session,redirect,url_for,flash
from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField
from wtforms.validators import Required
app=Flask(__name__)
app.debug=True
app.config['SECRET_KEY']='something key'
class NameForm(FlaskForm):
name=StringField('Value1:',validators=[Required()])
submit=SubmitField('Submit')
@app.route('/',methods=['GET','POST'])
def index5():
form=NameForm()
print(form.errors)
if form.validate_on_submit():
session['name']=form.name.data
flash("submited")
return redirect(url_for('index5'))
return render_template('index5.html',form=form,name=session.get('name'))
if __name__ =="__main__":
app.run()
index5.html
{% extends "base.html"%}
{% block title%}Send Somethings{% endblock%}
{% block content %}
<div class='w3-panel w3-yellow'>
<h1>Hello,Please input something</h1>
<h2>What you input:{{name}}</h2>
</div>
<form method="POST">
{{ form.name.label}}
{{ form.hidden_tag() }}
{{ form.name()}}
{{ form.submit()}}
</form>
{% endblock%}
python3 main.py
F5押すともうPOPUP出てなくなってます。
サーバー側:

Stackflowはvalidate_on_submit()が確実に動かないときの対応法など書いてます↓
https://stackoverflow.com/questions/10722968/flask-wtf-validate-on-submit-is-never-executed
流石にちょっと疲れた…
メール:soup01searchingtheworld@gmail.com