GAEを触る 多対多どうするの?

最近技術的なことをやれていなかった….(何かやらねば,何か書かねば) 今日はちょっとGAEをいじった.(HelloWorldでとまっていたもんで…) 何かサービスを….とはいかずとりあえず,こちらのBLOGを移行するようなイメージでGAEに慣れようかと.

さっそく,迷ったのが多対多!Blogのタグつけ機能を!と思ったのですが,DjangoのManyToManyの同じもんがないのかなぁ〜? ○○Propertyって色々あるんだがーどれが適当なんでしょ? 正しい道なんてわからないのでーとりあえず触ろうよ!(その後,どなたからかアドバイスもらおう!ははは)

てーな,感じでスタートしたもののーめっちゃ中途半端な形で終わってしまった. 作りたいものは,Blogのタグづけなんですが,GoogleBoomarkなどのタグづけのようにカンマ区切り(自分はスペース区切り)などのテキスト入力に対応したいなぁ〜と.

多対対に関しては,中間テーブルを自分でこしらえちゃった.

class Tag(db.Model):
    """ タグモデル(抜粋)"""
    name         = db.StringProperty()

    def __unicode__(self):
        return self.name

class Blog(db.Model):
    """ ブログモデル(省略)"""
    index        = db.StringProperty()
    title        = db.StringProperty()
    content      = db.TextProperty()
    created_at   = db.DateTimeProperty(auto_now_add=True)
    updated_at   = db.DateTimeProperty()
    is_published = db.BooleanProperty(default=True)
    is_active    = db.BooleanProperty(default=True)

    # ここでタグのリストゲットしようかと
    def tags(self):
        blog_tags = BlogTag.gql(
            "WHERE blog = :blog", blog = self
        )
        return [blog_tag.tag for blog_tag in blog_tags]

class BlogTag(db.Model):
    """ 多対多処理用に用意したモデル """
    blog         = db.ReferenceProperty(Blog)
    tag          = db.ReferenceProperty(Tag)

さて,BlogTagモデルにどうやってデータ(key)を突っ込もうかしら…とりあえず,ModelFormを作ろう.

class MultiTagField(forms.CharField):
    """ タグ入力フィールド作成 """
    def clean(self, value):
        values = []
        for name in value.replace('\u3000', ' ').split(' '):
            if len(name):
                tag = Tag.gql("WHERE name = :1", name).get()
                if tag is None:
                    tag = Tag(name = name).put()
                values.append(tag)
        if not len(values):
            raise forms.ValidationError(_('This field is required.'))
        return values

class BlogForm(djangoforms.ModelForm):
    """ Blogモデルフォーム """
    tags = MultiTagField()

    class Meta:
        model   = Blog
        fields  = ('index', 'title', 'content', 'tags')
        exclude = ('created_at', 'updated_at', 'is_published', 'is_active')

ほんで,これに対して,viewから登録…

def create_object(request):
    """ Blog作成部分の一部 """
    form = BlogForm(request.POST or None)
    if request.method == 'POST':
        if form.is_valid():
            # form.save()
            cleaned_data = form.cleaned_data
            index = cleaned_data['index']
            title = cleaned_data['title']
            content = cleaned_data['content']
            blog = Blog(index=index, title=title, content=content)
            blog.put()
            # タグ登録 ここでやるのひどいね.
            for tag in cleaned_data['tags']:
                blog_tag = BlogTag(blog = blog, tag = tag)
                blog_tag.put()
            return HttpResponseRedirect(
                reverse(
                    'blog_object_detail', kwargs={"key" : blog.key()}
                )
            )

ん〜「とりあえず,とりあえず」なんてやっていたらー完全に中途半端になってしまった…. このままじゃたぶん,編集画面とかエラー画面とかのときに対応できてないよね.ふふふ

Python温泉までにもうちょっといじっておかねば!

[Django] [GoogleAppEngine] [Python]

2008/06/08 02:55 | Comments(0)

Comments

Comment Form