Teclab3
- 6. python の特長
•シンプルな文法
•最初からオブジェクト指向
•手続き型みたいな書き方もできる
•拡張が C/C++ でもかける
•適当に書いても速い
•OS の深いところまで触れる
•最新は 3.3.x 系
•仕事で使う & 最初の一歩は 2.7.x 系
- 10. python の開発環境
•pythonbrew
•virtualenv, virtualenvwrapper
•easy_install, pip
•SublimeText2
※インストール方法は事前資料を参考。
https://gist.github.com/glassesfactory/5192223
- 15. Flask
MVC のうち、Cに関わる部分をやってくれる。
非常にシンプルにかけるため、ちょっとした API を構築する時便利。
- 18. Hello World!
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "hell world"
if __name__ == '__main__':
app.run()
- 19. テンプレート周り
•jinja2 + pyjade
jinja2 を jade 形式で記述
•install
$(techlab3) pip install pyjade
•使えるようにする
app = Flask(__name__)
app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
@app.route('/'):
return render_template('index.jade')
- 20. 書き方
jade の基本構文
変数とメソッド
- 23. mongodb
ドキュメント指向データベース。
RDBMS ではなく NoSQL に分類。
レコードをテーブルに格納するのではなく
構造データをJSON形式で表現する。
構造データの集合体をコレクションと呼ぶ。
- 24. mongodb のメリットデメリット
メリット
•とても気軽に使える。モックレベルならさくさく。
•単純なデータの I/O が速い
•動的にフィールドを追加できる
デメリット
•MySQL などと違いデータの型指定が厳密でない
•柔軟すぎるがゆえに事故が起こる
- 26. つかってみる
接続/切断
from mongoengine import *
con = connect('db_name')
con.disconnect()
モデル
from datetime import datetime
from mongoengine import *
class Tweet(Document):
sid = SequenceField(unique=True)
text = StringField(required=True)
created_at = DateTimeField(default=datetime.now)
updated_at = DateTimeField(default=datetime.now)
- 27. つかってみる
新規作成 取得
#保存 #コレクション取得
tweet = Tweet(text='hage') for tweet in Tweet.objects():
tweet.save() logging.info(tweet.text)
更新 削除
hironori.text = 'boorin' hironori.delete()
hironori.save()
- 29. モデル定義
from datetime import datetime
from mongoengine import *
class Tweet(Document):
sid = SequenceField(unique=True)
text = StringField(required=True)
created_at = DateTimeField(default=datetime.now)
updated_at = DateTimeField(default=datetime.now)
- 30. model.py
•Tweet モデルを書く
•db とのコネクションを管理する DBI を書く
- 31. ルーティング
単純な CRUD を実装する上で
以下のようなルーティングを定義する。
•一覧 => / [GET]
•詳細 => /1, /2, /3... [GET]
•新規 => /new [GET]
•保存 => / [POST]
•更新 => / [PUT]
•削除 => / [DELETE]
- 32. リクエストタイプに応じたレスポンス
json を要求されたら json を返す。
そうでなければ HTML を返す
→レスポンスのファイルタイプが異なるだけで
ほとんどの処理が同じになる場合が多いため。
@app.route('/index.json', method=["GET"])
@app.route('/', method=["GET"])
def index():
#リクエストが json だったら
if request.headers['Content-Type'] ==
'application/json':
return #json 返す
else:
#そうでなければ html を返す。
return render_template('index.jade')
- 33. db から引っ張り上げる
事前に定義した DBI を使って
mongodb との接続を確立しつつ、データをひっぱる。
from model import db, Tweet
with db:
collection = Tweet.objects.all()
- 34. データの整形
mongodb からのデータを
そのまま json にしようとするといくつかのデータは型が
存在しないと怒られるので整形する。
def model_serializer(model):
result = {}
for k in model:
val = model[k]
if isinstance(val, (str, basestring, int, float)):
result.setdefault(k, val)
elif isinstance(val, list):
l = [model_serializer(v) for v in val]
result.setdefault(k, l)
elif isinstance(val, dict):
result.setdefault(k, model_serializer(val))
elif isinstance(val, datetime):
result.setdefault(k, val.strftime('%Y/%m/%d %H:%M:%S'))
elif isinstance(val, Document):
result.setdefault(k, model_serializer(val))
elif isinstance(val, ObjectId):
result.setdefault(k, str(val))
return result
- 35. json にして返す
python には 2.6 からデフォルトで
json のパーサーが備わっているため
特に細かいことを気にする必要はない。
import json
json.dumps({'hoge':'huga'})
- 36. データの保存
フォームからのデータを引っ張ってきて
モデルへ突っ込んで保存する。
@app.route('/create', methods=["POST"])
def create():
data = request.form
tweet = Tweet(text=data["text"])
try:
tweet.save()
except Exception:
print e
serialized = modelSerializer(tweet)
resData = json.dumps(serialized)
return Response(resData, content_type="application/json",
status=200)
- 37. データの削除
@app.route('/<int:id>', methods=["DELETE"])
def destroy(id):
with db:
try:
tweet = Tweet.objects(sid=id).first().delete()
datas = json.dumps({'id': tweet.sid})
except:
# raise
return Response(datas, mimetype="application/json", status=200)
- 38. データの更新
@app.route('/<int:id>', methods=["PUT"])
def update(id):
data = request.form
with db:
tweet = Tweet.objects(sid=id).first()
tweet.text = data['text']
tweet.updated_at = datetime.now()
try:
tweet.save()
except Exception, e:
print e
serialized = model_serializer(tweet)
resData = json.dumps(serialized)
return Response(resData, mimetype="application/json", status=200)