【snake】Section: 11 Creating a Contact Form
requirements.txtに追加する。
Celeryを使えばタスクを別のスレッドやマシンに分散することができる。このタスクを分散させる仕組みをタスクキューといい、Celeryのプロセスは新しいタスクが入ってきていないかタスクキューを監視する。よくわからんけど、redisがメッセージの運び屋で、celeryが振り分け処理をするらしい。
# Data and workers. redis==2.10.5 celery==3.1.23 # Forms. Flask-WTF==0.9.5 WTForms-Components==0.9.7 # Extensions. flask-debugtoolbar==0.10.0 Flask-Mail==0.9.1
WTForms-Componentsは別の作者が作ったもので、
wtfより更にいろんなformを使えるようになる。
e-mailの設定方法
config/setting.pyでサーバーなどの設定を行う。
instance/setting.py ここに登録しておく。
lib/flask_mailplus.py これを設定することでパラメーターが使えるようになる。
Contact Blueprint
blueprints/contacts/forms.pyを新しくblueprintを追加している。
追加したblueprintをapp.pyでインポートする。
そして、55行目でregisterされている。
Extentionに色々追加されている。 mailエクステンションやFlask wtf packgeからcsrfが登録されている。
Views.pyに関して
場所は、snakeeyes/blueprints/contact/views.pyである。
形は他のblueprintと同じである。
①インポートして
②blueprint作って
③roteを作る。
ここからは各行ごとの役割を解説する。
14行目は、methods=['GET', 'POST'] はhtmlの出し入れを行う
25行目は、submitされた際にメッセージを表示させる。
26行目は、送信後に contact.index にリダイレクトさせる。
28行目は、indexに送る。form=formは、flaskがjinja2へvariableを送る方法。
今回はwtu formが使われている。16行目でform定義されている。
つまり、18行目のif文でエラーがなければflashメッセージが表示されリダイレクトする。
TemplatesとMacrosに関して
fは for macro のfである。
【Macrosの説明は意味がわからないので飛ばす。】
blueprints/contact/templates/contact/index.html を使う。
call f.form_groupを使う。
macroを使って、エラーチェックをする。
次にform tagである。
ここではcall f.form_tagを使う。
全てのタグを送込んでくれるmacroらしいが、現時点ではいまいちよく分からない。
Flask-WTForms
EmailFieldはwtfではないのでwtforms_componentsからインポートしている。
ContactFormを作る。wtfからFormを受け継いでくる。
入力文字数は制限した方がいい。→ Length(3, 254)]こんな感じ。
views.pyを見て見る。
9行目でContactFormをインポートする。
16行目でインスタント化している。
18行目でif文で確認を行なっている。
/contact/index.html を確認して見るとemaiフィールドとmessageフィールドがある。
emailとmessageは、適切に入力されているか確認するform.pyとマッチングするようになっている。
Celeryでメールを送る。
16〜17行目は、/0はredisのデータベースの名前である。
18〜20行目は、jsonのみ受け入れできるようにしている。セキュリティ状の問題である。
21行目は、コネクション制限である。
メールの設定方法
メールアドレスとパスワードを設定する。
その際にgoogleでアプリパスワードの設定が必要。
続けてパスワードの設定をする。
実際に試してみる メールをgmail.comで確認できる。
Celery with Docker Compose
docker-compose.ymlが何を書いてるか読み解く。
病むファイルは、コンテナに自動で環境設定してくれる環境設定まとめファイル。
6行目は、パスワードを設定する。configファイルとマッチさせなければならない。マストではない。
8行目は、volume。これを設定することでコンテーナーを止めてから変更したものなどを保存できる。次にコンテナを起動させて場合もそのデータは失われない。
34行目と36行目は同じ名前になる。
10行目は、ポート番号を入力する。これはredisのデフォルト設定。
更なる詳細は以下の通りである。
version: '3' # docker-composeの使用バージョン services: # コンテナから作られるサービス達。コンテナの設定を以下に。 nginx: # コンテナの名前 build: # イメージ(コンテナのテンプレ)を作るためのDockerfileがある場所 context: ./nginx # Dockerfileの場所 depends_on: # 対象のコンテナとリンク。 /etc/hostsにローカルipが書かれる - php # 172.17.0.3 php とか書かれる ports: # 公開port - 80:80 # 外部公開ポート番号 : コンテナのポート番号 volumes: # マウント。コンテナのデータと、手元のデータが同期する。 - ./www:/var/www:cached # 手元のパス : コンテナのパス : キャッシュオプション php: ~略~ mysql: restart: always # コンテナが止まった時に再起動する image: mysql:latest # コンテナを作るためのイメージ volumes: - ./mysql:/var/lib/mysql environment: # 環境変数の設定 - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - MYSQL_DATABASE=${MYSQL_DATABASE} ports: - 3306:3306
Confirming Tests:コンタクトページが動いているかテストする
asert分とは、成立している確認する関数。予期しない値を持った際には AssertionError を発生させ、エラーメッセージとともにプログラムを停止します。
assert 条件式, メッセージ #メッセージは省略することができます。
今回見るテストコードは前回と違いpost requestを実行するテスト。
14行目でtest_contact function内にformを辞書型で作りその中にemailとmessage書く。
19行目でpost clientを使ってdata(form)を送り込んでredirectさせる。
21行目でassert文を使ってresponseがthanksメッセージ付きの200か確認する。
assert_status_with_messageファンクションを確認する。
メッセージ付きのcustom assertionsを作る。
カスタムアサーションが何をするこというとメッセージ付きのresponseが帰って来るか確認する。13行目でstatus_codeを確認する。14行目で特定のhtm形式のメッセージを受け取れるかを確認する。
test_task.pyに関して
Cellery taskがどう動くかとflaskのメールextentionのoutboxがど動くかを理解できる。
8行目で辞書型でformを作る。
13行目でoutboxにメールを送る。
16行目でassert文を使って1通のみ送られたかをテストする。
17行目でoutboxの1文目がemailであるかをテストする。
実際にコードがtestを試して見る。
$ docker-compose exec website snakeeyes test
実行すると6つのテストのpassを確認できる。
コンタクトページの何割をtestコードでカバーしているか確認する。
$ docker-compose exec website snakeeyes cov
実行すると100%クリアであると確認できる。