チュートリアルで簡易掲示板みたいなのを動かしてみて、なんとなくわかったこと
- python はvbやc#のようなbegin..endや{ } の代わりに、インデントで文を区切る
- データベースに登録するクラスは class XXX(db.Model) で定義する
データストアクラスを作る
まず展覧会案内葉書に必要な項目について考える
- データ作成者
- データ作成日(更新日)
- 葉書の画像URL、裏表あるので、複数のリンクを保存する必要がある
- 展覧会タイトル
- 展覧会開始日、終了日
- 開場時間
- 会場
- 会場住所
- 地図
- イベント(オープニングパーティがあるよ!とか、最終日は4時までとかの情報
クラスのメンバは
db.UserProperty
db.StringProperty
db.DateTimeProperty
等の型が使える
Types and Property Classesに一覧がある。
DateTimePropertyには作成時に現在の日付を初期値として自動的に割り当てることができる。でも日本との時差で9時間ずれている
LinkPropertyとかEmailPropertyなんてものもあるけど、よくわからないのでStringPropertyにして、葉書画像のリンクの様に複数データが必要なものはStringListPropertyとした
class PostCard(db.Model):メインページの表示を作る
author = db.UserProperty()
images = db.StringListProperty()
title = db.StringProperty()
members = db.StringListProperty()
update = db.DateTimeProperty(auto_now=True)
date_s = db.DateProperty()
date_e = db.DateProperty()
opentime = db.TimeProperty()
closetime = db.TimeProperty()
place = db.StringProperty()
address = db.PostalAddressProperty()
zip = db.StringProperty()
phone = db.PhoneNumberProperty()
point = db.GeoPtProperty()
content = db.StringProperty(multiline=True)
comment = db.StringProperty(multiline=True)
closed = db.StringListProperty()
events = db.StringListProperty()
visible = db.BooleanProperty()
メインページはurl:http://forlune.appspot.com/にアクセスしたときに表示するhtmlを生成する
チュートリアルを改造して MainPage クラスを作る
GETリクエストを受け取ったときの処理を記述
class MainPage(webapp.RequestHandler):GET リクエストで受け取るクエリとして
def get(self):
.....
kind=all,yyyy-mm-dd
start=n
maxcount=n
span=day,week,month
とする。kind=allでPostCardを全て表示する、日付を指定するとその日以降開催している展覧会の葉書を表示する様にする
spanで表示期間を1日,1週間,1ヶ月とする
start,maxcountで表示する枚数を制限する
プログラムでクエリはPOST,GETリクエストともに
self.request.get('kind')
の様に受け取る
文字列を数値に変換するために int() 関数を使う、変換に失敗したら例外が発生するので、例外処理も含めておく
try:PostCardをデータベースから取り出す
start=int(self.request.get('start'))
except:
start=0
entitys=PostCard.all().order('-update')これで全部のPostCardを更新順に取り出せる
指定した日付で終了していないPostCardを取り出す
データベースから条件を指定してデータを取り出すには、gqlとかいうのを使うらしい
Getting Entities Using a Query
gqlはsqlに似たデータベース言語だけど、sqlすら使ったこと無いので良くわからん
よくわからないけど、日付で範囲を指定してデータを取り出すには以下の様に記述すると出来た
entitys = PostCard.gql("WHERE date_e >= :1 "+"ORDER BY date_e LIMIT 10",startdate)ここでstartdate は表示する期間の開始日をセットしてある、同じように終了日をenddateに設定してる。つまり4/1から一週間の間に開催中の展覧会を表示したい場合はstartdateに4/1、enddateに4/7をセットする
本当は、指定した期間内に開催中のPostCardを抽出するようにしたいのだけど、gqlでは抽出条件に異なるプロパティに対して不等号を条件として設定することが出来ないみたい?
例えば date_s <=enddate AND date_e >= startdate こういう条件はダメ?
仕方が無いのでenddate側の絞込みはプログラムでやってみる
entitys = [entity for entity in entitys if entity.date_s <= enddate]これはリストの内包表記というやつで、
new_entitys = []を簡単に書ける
for entity in entitys:
if entity.date_s <= enddate:
new_entiys.append(entity)
entitys = new_entitys
これをやっちゃうとentitysもうQueryクラスではなくてリストになる?
Queryクラスってのが、いまひとつ理解できてないけど、リストとは違うみたい
ここには
って書いてあった。クエリの結果にアクセスするにはfetch()、かイテレータインターフェイスとある。上記の場合はイテレータインターフェイスということになるのかなQueryオブジェクトもGqlQueryオブジェクトも、実はアプリがその結果にアクセスしようとするまではクエリを実行しないんだ。つまり、アプリが結果にアクセスしようとした時にクエリが実行され、Modelクラスのインスタンスとしてメモリに読み込まれるってコトだな。ちなみに、どっちのクラスも結果へのアクセス方法は2つある。1つがfetch()メソッドを使う方法、そしてもう1つがイテレータインターフェースだ。
fetch()メソッドは返却される結果の上限値を「fetch(上限値)」の形式で表現するぜ!それからオプションでスキップするオフセットを指定する事もできる。書き方としてはfetch(上限値, offset=オフセット値)って感じになる。上限値の部分で指定してるのが、datastoreから引っ張ってくる結果の数で、オフセットで指定するのが実際にメソッドの結果として返される結果の数ってコトになってるゼ! 簡単にまとめると、まずはメモリ上に上限値までの全ての結果を引っ張ってきて、それから初めてオフセットに従った結果を返す為の処理が行われるってワケだな。つまり、オフセットで指定する値はdatastoreからとってくる結果の数には影響を与えなくて、あくまでもfetch()メソッドの実行結果を返す段階で使われるダケって話だ。
つづく
0 件のコメント:
コメントを投稿