Flask#Tempate,Form

こんばんわ。Flaskの勉強第二話です。第一話はこっちらでみてだくさい↓

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

結果はこんな感じです:

flask3

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

flask4

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

flask2JPG

サーバー側の反応からみえると…

ではどうやって?
<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

s4

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

s3

サーバーから見ると…

ではどうやって?

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を使います。↓

w3.css

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です。↓

s6

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

s8

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

s12

サーバー側:

s11

ではどうやって?
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を押したときなにか変と思わないか?

s13

これは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出てなくなってます。

サーバー側:

20

Stackflowはvalidate_on_submit()が確実に動かないときの対応法など書いてます↓

https://stackoverflow.com/questions/10722968/flask-wtf-validate-on-submit-is-never-executed

流石にちょっと疲れた…


メール:soup01searchingtheworld@gmail.com

Footer_Basic

Please Support some devices for my blog

Amazon Gift List

Find ME

Twitter:@3threes2
Email:soup01threes*gmail.com (* to @)
YoutubeChannel:https://www.youtube.com/channel/UCQ3CHGAIXZAbeOC_9mjQiWQ

シェアする

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

フォローする