こんばんわ。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