AppEngine数据库模型有has_key()方法但不可迭代?

时间:2014-08-16 09:02:30

标签: python google-app-engine dictionary cheetah

我得到了:类型' Lantern'在其中一个模板引擎文件(Cheetah)中不可迭代。你可以猜到 obj 是一个灯笼(见下文)。

NameWrapper.py:

if hasattr(obj, 'has_key') and key in obj:

这是我的模型的简化版本。没什么好看的,没有其他方法只是属性声明。

models.py:

from google.appengine.ext import db

class Product(db.Model):
    name = db.StringProperty(required=True)

class Lantern(Product):
    height = db.IntegerProperty()
  1. 我该如何解决这个问题?
  2. 是否正确,AppEngine模型具有 has_key 功能但可迭代
  3. 溶液(编辑):

    我已经更换了这条线。

    if hasattr(obj, 'has_key') and isinstance(obj, collections.Iterable) and key in obj:
    

2 个答案:

答案 0 :(得分:3)

NameMapper实现错误地假设使用has_key()方法使Model类成为映射并尝试测试密钥成员资格。

这是Cheetah NameMapper实施中的一个错误,应该报告给项目。您可以尝试禁用NameMapper功能,文档建议it is optional并可以使用useNameMapper编译器设置进行切换。我不熟悉语法,但尽量避免依赖模板中的功能。

如果您不反对编辑Cheetah代码,可以用以下代码替换测试:

from collections import Mapping

if isinstance(obj, Mapping) and key in obj:

使用正确的Abstract Base Class来检测映射对象。

Model个对象不是映射Model.has_key()函数不测试是否存在映射键,它是一种测试对象是否具有数据存储键的方法。

该方法的文档字符串是:

def has_key(self):
    """Determine if this model instance has a complete key.

    When not using a fully self-assigned Key, ids are not assigned until the
    data is saved to the Datastore, but instances with a key name always have
    a full key.

    Returns:
      True if the object has been persisted to the datastore or has a key
      or has a key_name, otherwise False.
    """

请注意,除了自动绑定self之外,上述方法不会带参数。

Model.has_key()似乎是Google未在Model Class documentation中添加的便捷方法;如果Model.key() method会抛出False例外,它会返回NotSavedError

在任何情况下,Model个对象都不是序列;他们没有__iter__方法,也没有长度或支持索引。因此,它们不可迭代。使用has_key()方法并不意味着它们应该是。

答案 1 :(得分:1)