2009年6月15日 星期一

為儲存的內容加上標籤(簡單版)

現在很多網站都會為儲存的內容加上標籤,像 Flickr 的每一張相片都可以設定標籤:



或是像 delicious 的書籤也可以設定標籤:



在 App Engine 上開發應用程式,如果要為儲存的內容加上標籤的支援,那麼在資料模型(Data Model)的定義時,可以加上一個 property:
from google.appengine.ext import db
class MyContent(db.Model):
....
tags = db.StringListProperty()

如此一來,tags就可以儲存由字串所組成的 list資料,也就是可以儲存 MyContent 物件的標籤。

假設使用者透過表單送出標籤的資料,而標籤的資料是一個以逗號(,)隔開的字串,那麼要儲存標籤的作法就是:
....
tags_string = self.request.get('tags')
content = MyContent()
....
content.tags = map(lambda x: x.strip(), tags_string.split(','))
content.put()
....

雖然 tags_string.split(',') 已經產生一個由字串所組成的 list 了,但是使用者輸入的字串,可能會在逗號的前後留下空白,所以用了 map 函數將 list 中的每個元素空白消掉(strip 函數)

如果要取出含有某個標籤值(如:food)的內容,則可以直接使用 GQL 中特殊的語法來取出:
....
query = MyContent.gql('WHERE tags = :1', 'food')
for content in query:
....

因為 GQL 的設計,雖然 tags 欄位是一個 list,但是只要比對的元素有出現在 list 中,則 = 運算的結果就會是 True,所以就能夠輕易地根據 list 中的元素來查詢資料。

2 則留言:

  1. 您好,想請問一下,在gae中有個CategoryProperty,為什麼你不用這個來存tag而是要用StringListProperty?

    回覆刪除
  2. @shian
    您這樣也可以,那麼就得要把 tags 的屬性改成
    tags = db.ListProperty(db.Category)

    然後查詢時就要

    query = MyContent.gql('WHERE tags = :1', db.Category('food'))
    ....

    只是若是我沒有將 data model 輸出成 xml 或是需要其它特殊的動作,那麼我就會簡單地用 str 能完成就用 str

    回覆刪除