近日,google app engine推出了open source projects,已有近20个项目加入。taggable-mixin也是其中之一,由Adam Crossland主持维护。

Taggable 是一个Python mixin class,可以添加在任何从Google App Engine db.Model 继承的类中。taggable主要通过get_tags_as_string、set_tags和set_tags_from_string等方法实现对 tag的存取。以下是我对taggable进行的尝试:

在使用taggable前,首先把 taggable.py 复制到您的application目录。

model

from google.appengine.ext import db
import taggable

class shop(db.Model, taggable.Taggable):
  owner = db.UserProperty(required=True)
  name = db.StringProperty(required=True)
  slug = db.StringProperty(required=True)
  logo = db.BlobProperty()
  description = db.TextProperty()
  created = db.DateTimeProperty(auto_now_add=True)

  def __init__(self, parent=None, key_name=None, app=None, **entity_values):
    db.Model.__init__(self, parent, key_name, app, **entity_values)
    taggable.Taggable.__init__(self)

view

class MyShop(BaseHandler):
  @requires_login
  def get(self):
    shop = Shop.all().filter('owner = ', self.user).get()
    if shop:
      shop.get_tags_as_string()

    self.template_values.update({
      'shop': shop,
      })
    self.render('shop.html')

   @requires_login
  def post(self):
    name = self.request.get('name')
    slug = self.request.get('slug').strip().lower()
    description = self.param('description')
    logo = db.Blob(images.resize(self.param('logo'),128,128))

    shop = Shop.all().filter('owner = ', self.user).get()
    if not shop:
      shop = Shop(owner = self.user,
                  name = name,
                  slug = slug,
                  description = description,
                  logo = logo,
                  )
    else:
      shop.name = name
      shop.slug = slug
      shop.description = description
      if logo:
        shop.logo = logo
    shop.put()

    if (strip(self.param('tags')) != None):
      shop.set_tags_from_string(self.param('tags'))

    self.redirect('/shop/' + slug)

template

{% extends "base.html" %}

{% block title %}A taggable exmple{% endblock %}

{% block main %}
  <h1>My shop</h1>

  <form id="myShopForm" action="" method="post" enctype="multipart/form-data">
    Shop name: *<br />
    <input type="text" name="name" value="{{shop.name}}" />
    <br />Slug: *<br />
    <input type="text" name="slug" value="{{shop.slug}}" />
    <br />Description:<br />
    <textarea name="description" id="description" >{{shop.description|escape}}</textarea>
    <br />
    <img src="/showlogo/{{shop.slug}}" />
  	  <br />Logo:  (The picture will auto resize to 128 X 128px)<br />
  	  <input id="shoplogo" type="file" name="logo" accept="jpg|gif|png" />
    <p></p>
    <br />Tags: *<br />
    <input type="text" name="tags" value="{% for each_tag in shop.tags %}{{each_tag.tag}}{% if not forloop.last %}, {% endif %}{% endfor %}" />

    <input type="submit" value="Submit">
   </form>
{% endblock %}

taggable提供了对tag操作的便利,有兴趣的朋友可以移步http://code.google.com/p/taggable-mixin/获得更多信息,源码包中有详细的帮助文件。