My favorites | 中文(繁體) | Sign in
英文版或許有比此中譯版新的內容

Model 類別

Model 類別是資料模型定義的超級類別。

Model 是由 google.appengine.ext.db 模組所提供。

簡介

應用程式透過定義 Model 的子類別,來定義資料模型。模型的屬性使用類別屬性 (attribute) 和 Property 類別實例來定義。例如:

class Story(db.Model):
  title = db.StringProperty()
  body = db.TextProperty()
  created = db.DateTimeProperty(auto_now_add=True)

應用程式會藉由建議 Model 類別的子類別例項,來建立新的資料實體。實體的屬性可以使用例項的屬性 (attribute) 來指派,或做為建構函式的關鍵字引數。

s = Story()
s.title = "The Three Little Pigs"

s = Story(title="The Three Little Pigs")

模型子類別名稱會做為資料存放區實體種類的名稱使用。屬性 (attribute) 的名稱會做為實體上相應屬性的名稱使用。名稱以底線 (_) 開頭的 Model 實例屬性 (attribute) 會被忽略,所以您的應用程式可以用這類屬性 (attribute) 來儲存那些沒有儲存至資料存放區的模型實例資料。

資料存放區和模型類別 API 在屬性名稱和模型實例屬性 (attribute) 上有一些限制。請參閱不允許的屬性名稱以取得完整描述。

資料實體可以具有選擇性的父系實體。父子式關聯性組成實體群組,此群組會用來控制交易和資料存放區中的資料位置。透過將父系實體做為 parent 引數傳遞給子系的建構函式,應用程式會在兩個實體之間建立父子式關聯性。如需進一步了解父系和上階,請參閱金鑰和實體群組

每個實體都有金鑰,它是代表該實體的獨特識別項。實體可以具有選擇性的金鑰,此字串在整個指定的種類實體中是唯一的。Key.from_path()Model.get_by_key_name() 方法可以用實體的種類和名稱來抓取實體。如需關於金鑰的詳細資訊,請參閱金鑰和實體群組

方法 Model.get_or_insert() 可以用來抓取可能不存在的實體,並視需要在資料存放區中建立它:

keyname = "some_key"
s = Story.get_or_insert(keyname, title="The Three Little Pigs")

注意:Model 實例第一次明確地或透過 Model.get_or_insert() 進行 put()之後,在資料存放區中才會有相應的實體。

Model 類別是由 google.appengine.ext.db 套件所提供。

建構函式

Model 類別的建構函式定義如下:

class Model(parent=None, key_name=None, **kw)

資料模型定義的超級類別。

引數:

parent
實體的 Model 實例或 Key 實例是新實體的父項 (parent)。
key_name

新實體的名稱。名稱會成為主要金鑰的一部分。若為 None,則會使用系統產生的 ID 做為金鑰。

key_name 值的開頭不能是數字,而且不能是 (__*__) 型式。 若您的應用程式以使用者提交的資料做為資料存放區實體金鑰名稱 (例如電子郵件地址),則應用程式要先處理好該值,例如加上已知字串的首碼 (像是「key:」),以符合這些要求。

key_name 會儲存為 Unicode 字串,而 str 值會轉換為 ASCII 文字。

**kw
實例屬性的初始值 (做為 keyword 引數)。每個名稱會與 Model 類別上定義的屬性 (attribute) 相應。

類別方法

Model 類別提供下列類別方法:

Model.get(keys)

取得指定 Key 物件的模型實例。金鑰必須代表該模型種類的實體。若提供的金鑰種類不正確,會引發 KindError

此方法類似於 db.get() 函式,但是多了類型檢查。

引數:

keys
Key 物件或 Key 物件的清單。也可以是 Key 物件的字串版本或字串的清單。
Model.get_by_id(ids, parent=None)

取得指定數字 ID (或 ID) 的模型實例。

引數:

ids
數字實體 ID,或數字實體 ID 的清單。
parent
要求實體的父系實體,做為 Model 實例或 Key 實例,或者 None (預設),若要求的實體沒有任何父系。 單一呼叫所要求的多個實體必須具有相同父系。

ids 是代表一個名稱的字串,則該方法會傳回該名稱的模型實例,或者 None,若該實體不存在。若 ids 是清單,則方法會傳回模型實例的清單。當相應的 Key 沒有任何實體存在時,則傳回 None

Model.get_by_key_name(key_names, parent=None)

取得指定金鑰名稱的模型實例。

引數:

key_names
金鑰名稱,或金鑰名稱的清單。
parent
要求實體的父系實體,做為 Model 實例或 Key 實例,或者 None (預設),若要求的實體沒有任何父系。 單一呼叫所要求的多個實體必須具有相同父系。

key_names 是代表一個名稱的字串,則該方法會傳回該名稱的模型實例,或者 None,若該實體不存在。若 key_names 是清單,則方法會傳回模型實例的清單。當相應的 Key 沒有任何實體存在時,則傳回 None 值。

Model.get_or_insert(key_name, **kwds)

使用單一交易、以指定金鑰名稱取得或建立模型種類的實體。交易會確認是否有兩個使用者同時使用指定名稱取得或插入實體,然後兩個使用者會有指向該實體的模型實例 (不論是由哪一個使用者的處理程序所建立)。

引數:

key_name
實體金鑰的名稱
**kwds
傳遞給模型類別的關鍵字引數 (若指定金鑰名稱的實例不存在的話)。若想要的實體具有父系,則 parent 引數為必要的。

此方法會傳回代表要求實體之模型類別的實體 (不論要求的實體確實存在或者是由此方法所建立)。與所有資料存放區操作相同,此方法可以引發 TransactionFailedError (若交易沒有完成)。

Model.all()

傳回 Query 物件,它代表與此模型相對應種類的所有實體。Query 物件的方法,可以在執行之前在查詢上套用篩選器和排序順序。請參閱查詢以取得詳細資訊。

Model.gql(query_string, *args, **kwds)

針對此模型的實例執行 GQL 查詢。

引數:

query_string
GQL 查詢的一部分,接在 SELECT * FROM model (使用此類別方法會隱含這個部分) 後面。
*args
位置參數繫結,與 GqlQuery 建構函式類似。
**kw
關鍵字參數繫結,與 GqlQuery 建構函式類似。
s = Story.gql("WHERE title = :1", "Little Red Riding Hood")

s = Story.gql("WHERE title = :title", title="Little Red Riding Hood")

傳回值是 GqlQuery 物件,可用來存取結果。

Model.kind()
傳回模型的種類,通常是 Model 子類別的名稱。
Model.properties()
傳回為此模型類別所定義之所有屬性的字典。

實例方法

模型實例具有下列方法:

key()

傳回此模型實例的 Key

模型實例必須 put() 至資料存放區,才會具有金鑰。若於實例具有金鑰之前就呼叫 key(),則會引發 NotSavedError

put()

在資料存放區中儲存模型實例。若模型實例是新建立的,而且尚未儲存,則此方法會在資料存放區中建立新的資料實體。否則,它會以目前的屬性值更新資料實體。

此方法會傳回已儲存實體的 Key

delete()

刪除資料存放區的模型實例。若實例從未執行 put(),則刪除不會有任何作用。

is_saved()

若模型實例已 put() 至資料存放區至少一次,則會傳回 True

此方法只會檢查該實例在建立之後,至少已儲存一次。它不會檢查上次執行 put() 之後,實例的屬性是否更新。

dynamic_properties()

傳回為此模型實例定義之所有動態屬性的名稱清單。這僅適用於 Expando 類別的實例。針對非 Expando 模型的實例,這會傳回空白清單。

parent()

傳回此實例之父系實體的模型實例,或者 None,若此實例沒有父系。

parent_key()

傳回此實例之父系實體的 Key,或者 None,若此實例沒有父系。

to_xml()

傳回模型實例的 XML 表示。

屬性值與 AtomGData 規格一致。

不允許的屬性名稱

資料存放區及其 API 在實體屬性名稱和模型實例屬性 (attribute) 上有一些限制。

只要屬性名稱的開頭和結尾是兩個底線字元 (__*__),資料存放區就會暫不處理。資料存放區實體不能有這種名稱的屬性。

Python 模型 API 會忽略 ModelExpando 開頭為底線 (_) 的所有屬性 (attribute)。 您的應用程式可以使用這些屬性 (attribute),將資料與尚未儲存至資料存放區的模型物件相互關聯。

最後,Python 模型 API 會使用物件屬性 (attribute) 來定義模型的屬性,而按照預設,資料存放區實體屬性會以屬性 (attribute) 命名。因為 Model 類別針對其他目的有幾種屬性和方法,在 Python API 中,這些屬性 (attribute) 不能做為屬性。例如,Model 不能具有以屬性 (attribute) key 存取的屬性。

不過,藉由將 name 引數指定給屬性建構函式,可以為資料存放區指定不同的名稱,而不使用屬性 (attribute) 名稱。這樣一來,可以讓資料存放區實體的屬性名稱與 Model 類別中保留的屬性 (attribute) 類似,並且在類別中使用不同的屬性 (attribute) 名稱。

class MyModel(db.Model):
  obj_key = db.StringProperty(name="key")

在 Python API 中,Model 類別保留下列屬性 (attribute) 名稱:

  • all
  • app
  • copy
  • delete
  • entity
  • entity_type
  • fields
  • from_entity
  • get
  • gql
  • instance_properties
  • is_saved
  • key
  • key_name
  • kind
  • parent
  • parent_key
  • properties
  • put
  • setdefault
  • to_xml
  • update