My favorites | 中文(简体) | Sign in

Model 类

Model 类是数据模型定义的超类。

Modelgoogle.appengine.ext.db 模块提供。

简介

通过定义将 Model 作为子类的类,应用程序可以定义数据模型。使用 Model 属性和 Property 类实例,可以定义 Model 的属性。例如:

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

通过实例化 Model 类的子类,应用程序可以创建新数据实体。实体的属性可以使用实例的属性来分配,也可以作为构造函数的关键字参数。

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

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

Model 子类的名称会被用作数据存储区实体类型的名称。属性的名称会被用作实体上对应属性的名称。名称以下划线 (_) 开头的 Model 实例属性会被忽略,因此您的应用程序可以使用这些属性来将尚未保存到数据存储区中的数据存储到 Model 实例上。

数据存储区和 Model 类 API 可以对属性名称和 Model 实例属性实施若干限制。有关完整说明,请参阅禁止使用的属性名称

数据实体可以有可选的父实体。父子关系可以形成实体组,用于控制数据存储区中的事务性和数据位置。通过将父实体传递到子实体的构造函数(作为 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")

注意:在第一次 put() Model 实例之前(明确地执行该操作或通过 Model.get_or_insert() 执行),Model 实例在数据存储区中并没有对应的实体。

Model 类由 google.appengine.ext.db 包提供。

构造函数

Model 类的构造函数定义如下:

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

数据模型定义的超类。

参数:

parent
新实体的父实体的 Model 实例或 Key 实例。
key_name

新实体的名称。该名称会成为主键的一部分。如果为 None,将为键使用系统生成的 ID。

key_name 的值不得以数字开头 也绝不能采用 __*__ 的形式。如果您的应用程序使用用户提交的数据来作为数据存储区实体的键名(例如电子邮件地址),则应用程序应先清理该值(例如为其添加“key:”等已知的字符串前缀),使其符合这些要求。

key_name 存储为 Unicode 字符串,str 值转换为 ASCII 文本。

**kw
实例的属性的初始值,作为关键字参数。每个名称都与 Model 类中定义的属性对应。

类方法

Model 类提供以下类方法:

Model.get(keys)

获取指定 Key 对象的 Model 实例。键必须代表 Model 类型的实例。如果提供的键类型不正确,就会引发 KindError

该方法类似于 db.get() 函数,但具有额外的类型检查。

参数:

keys
Key 对象或 Key 对象的列表。还可以是 Key 对象的字符串版本,或字符串列表。
Model.get_by_id(ids, parent=None)

获取指定数字 ID 的 Model 实例。

参数:

ids
数字实体 ID,或数字实体 ID 列表。
parent
所请求实体的父实体,是 Model 实例或 Key 实例,如果所请求实体没有父实体,则为 None(默认)。一个调用所请求的多个实体必须全部具有相同的父实体。

如果 ids 是代表一个名称的字符串,则该方法会返回该名称的 Model 实例,如果实体不存在,则返回 None。如果 ids 是一个列表,则该方法会返回 Model 实例的列表,如果对应的 Key 不存在实体,则返回 None 值。

Model.get_by_key_name(key_names, parent=None)

获取指定键名的 Model 实例。

参数:

key_names
键名或键名列表。
parent
所请求实体的父实体,是 Model 实例或 Key 实例,如果所请求实体没有父实体,则为 None(默认)。一个调用请求的多个实体必须全部具有相同的父实体。

如果 key_names 是代表一个名称的字符串,则该方法会返回该名称的 Model 实例,如果实体不存在,则返回 None。如果 key_names 是一个列表,则该方法会返回 Model 实例的列表,如果对应的 Key 不存在实体,则返回 None 值。

Model.get_or_insert(key_name, **kwds)

使用一个事务获取或创建具有指定键名的 Model 类型的实体。如果两个用户同时尝试使用指定的名称来获取或插入实体,则该事务可以确保两个用户都能拥有指向该实体的 Model 实例,而不管创建实体的过程如何。

参数:

key_name
实体的键名
**kwds
要传递给 Model 类的关键字参数(当具有指定键名的实例不存在时)。如果所需实体有父实体,则需要 parent 参数。

该方法会返回代表所请求实体的 Model 类的实例,与该实例是否存在或是否由方法创建无关。与所有数据存储区操作一样,如果无法完成事务,该方法会引发 TransactionFailedError 错误。

Model.all()

返回代表与该 Model 对应的类型的所有实体的 Query 对象。在执行 Query 对象上的方法之前,可以对查询进行过滤和排序。有关详细信息,请参阅 Query

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

对该 Model 的实例执行 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 子类的名称。
Model.properties()
返回为该 Model 类定义的所有属性的参照表。

实例方法

Model 实例有以下方法:

key()

返回该 Model 实例的数据存储区 Key

put() 入数据存储区之前,Model 实例没有键。在实例拥有键之前调用 key() 会引发 NotSavedError 错误。

put()

将 Model 实例存储在数据存储区中。如果 Model 实例是新创建的并且之前从未存储过,则该方法会在数据存储区中创建新的数据实体。否则,该方法会用当前属性值更新数据实体。

该方法会返回存储的实体的 Key

delete()

从数据存储区中删除 Model 实例。如果实例从未被 put() 到数据存储区,删除不会起任何作用。

is_saved()

如果 Model 实例至少已被 put() 到数据存储区中一次,则返回 True

该方法只会检查自实例创建后是否至少已存储过一次。它不会检查自最后一次被 put() 后实例的属性是否更新过。

dynamic_properties()

返回针对该 Model 实例定义的所有动态属性的名称列表。此方法仅适用于 Expando 类的实例。对于非 Expando 模型实例,此方法会返回空列表。

parent()

返回该实例的父实体的 Model 实例,如果该实例没有父实体则返回 None

parent_key()

返回该实例的父实体的 Key,如果该实例没有父实体则返回 None

to_xml()

返回 Model 实例的 XML 表示方法。

属性值符合 AtomGData 规范。

禁止使用的属性名称

数据存储区及其 API 对实体属性名称和 Model 实例属性实施若干限制。

数据存储区保留所有以两根下划线 (__*__) 开头和结尾的属性名称。数据存储区实体不能有此类名称的属性。

Python 模型 API 会忽略 ModelExpando 上所有以下划线 (_) 开头的属性。应用程序可以使用这些属性将数据与未保存到数据存储区的 Model 对象相关联。

最后,Python 模型 API 可以使用对象属性定义 Model 的属性,并且在默认情况下,数据存储区实体属性会根据这些属性进行命名。由于 Model 类具有用于其他目的的若干种属性和方法,因此这些属性无法用于 Python API 中的属性。例如,Model 无法使用属性 key 来访问属性。

但是,通过给属性构造函数赋予 name 参数,属性可以为数据存储区指定与属性名称不同的其他名称。这样,数据存储区实体可以拥有与 Model 类中保留的属性类似的属性名称,并可在该类中使用不同的属性名称。

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

以下属性名称为 Model 类在 Python API 中所保留的属性名称:

  • 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