gae 模型 get_by_id() 与 get_by_key_name() 的区别

8 投票
2 回答
3015 浏览
提问于 2025-04-16 18:58

我在想用 Model.get_by_key_name() 和 Model.get_by_id() 来获取记录有什么不同。

比如说,我要返回一些 JSON 数据,这些数据会用来显示一个记录的表格,每条记录旁边都有一个删除按钮。假设我有一个模型叫 'Foo',还有一个模型实例叫 'foo'。

我觉得我可以用以下两种方式来把每个按钮和对应的记录关联起来:

str(foo.key())  #suppose it eval's to "axhYm92ZZXJvY2tyDgsSCENhnb3J5GBQM"

或者

foo.key().id()  #suppose it eval's to "57"

其中一个值会放进一个 HTML 表单里,用户可以点击这个按钮,这样就会发送请求去删除对应的记录。

这个请求会导致以下结果:

Foo.get_by_key_name("axhYm92ZZXJvY2tyDgsSCENhnb3J5GBQM").delete()

或者

Foo.get_by_id(57).delete()

现在,作为一个总是犹豫不决的程序员,我想知道……哪种方式是“正确”的?这两种方式似乎都能用,但有没有什么情况让其中一种更好?使用 'key' 的方式和使用 'id' 的方式有什么优点吗?

2 个回答

2

你得到的是一个键字符串,而不是键名称。如果你想通过这个键字符串来获取一个对象,你可以使用 Model.get(keystring)。键名称是你给一个对象分配的,应该是唯一的。如果你觉得可以用任何唯一的属性作为键名称,那就可以这样做;否则就用默认生成的ID。使用键名称的唯一好处是可以用 get_or_insert() 这个方法,它会先检查是否已经有这个键名称的实体,如果有就返回它,如果没有就创建一个新的实体并返回。

11

你把键的名字和字符串形式的键搞混了。它们是不同的。键的名字是你在创建一个实体时,通过一个叫做key_name的特殊属性给它指定的。如果你不指定,系统会自动生成一个ID。一个实体的键可以有名字或者ID,但不能同时有。

如果你故意把一个键转换成字符串形式,你可以通过把它传回键的构造函数来恢复它。

stringifiedKey = str(key)
reconstitutedKey = db.Key(stringifiedKey)

假设你真的是在说名字和ID的区别,这其实就是看哪个更方便。性能上的差别几乎可以忽略不计。

撰写回答