PolyModel @ Timeline

先日のGoogle App EngineのSDK1.1.8のリリースで、PolyModelが使えるようになったので、さっそくGAWareで使うことにした。今までは、TimelineとImageはBaseModelで作っていた。そして、書きソース(Pastebinで見る)のように、一度Imageを積み込み、そのkey().id()をTimelineのIntegerPropertyに突っ込んでた。そして取得するときは、image = Image.get_by_id(timeline.photo)という風に取得していた。

from appengine_django import models
from google.appengine.ext import db

class Timeline(models.BaseModel):
    """
    Usage::
        user = users.get_current_user()
        message = 'test'
        timeline = Timeline(author = user, message = message)
        timeline.save()
    """
    author = db.UserProperty()
    message = db.StringProperty(_('message'), required=True)
    photo = db.IntegerProperty()

class Image(models.BaseModel):
    author = db.UserProperty(required=True)
    # image
    data = db.BlobProperty(required=True)
    format = db.StringProperty(required=True)

from google.appengine.api import users, images
from django.core.files.uploadedfile import SimpleUploadedFile as UploadedFile

file = request.FILES['image']
format = file.content_type
data = images.Image(file.read())._image_data
author = users.get_current_user()
image = Image(author = author, data = data, format = format)
image.put()
timeline = Timeline(author = author, message = 'test', photo = image.key().id())
timeline.put()

今後、どこかのサービスのように画像以外に、リンクや、Youtubeのビデオ、ファイルなどをアップできるようにする時は、Timelineを改造しないといけない(※実際は定数で、Timelineが何を含んでいるのかを持っていた)。でっ待望のPolyModelに書き換えた。

from appengine_django import models
from google.appengine.ext import db
from google.appengine.ext.db import polymodel

class Timeline(polymodel.PolyModel):
    """
    Usage::
        user = users.get_current_user()
        message = 'test'
        timeline = Timeline(author = user, message = message)
        timeline.save()
    """
    author = db.UserProperty()
    message = db.StringProperty(_('message'), required=True)
    photo = db.IntegerProperty()

class ImageTimeline(Timeline):
    # image
    data = db.BlobProperty(required=True)
    format = db.StringProperty(required=True)

    @classmethod
    def class_name(cls):
        return 'Photo'

from google.appengine.api import users, images
from django.core.files.uploadedfile import SimpleUploadedFile as UploadedFile

file = request.FILES['image']
format = file.content_type
data = images.Image(file.read())._image_data
author = users.get_current_user()
image = ImageTimeline(author = author, message = 'test', data = data, format = format)
image.put()

# get photos
imagetimelines = Timeline.all().filter('class =', 'Photo')

PolyModelを使うと、あるモデルを派生してかけるので、Timelineに持たせたいアイテムが増えたら増えた分だけモデルを書いていけばいい。影響範囲は案外少ない(diffはここ)。拡張したくなりそうなモデルはすべてPolyModelで。

コメント

このブログの人気の投稿

Python から Win32 API 経由で印刷する

Disqus のスケール - Django 編

#PySpa アドベント (23 日目)