3

我得到:“Lantern”类型的参数在模板引擎文件之一(Cheetah)中不可迭代。你可以猜到obj是一个 Lantern(见下文)。

NameWrapper.py:

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

这是我的模型的简化版本。没什么花哨的,没有额外的方法只是属性声明。

模型.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但不可迭代

解决方案(编辑):

我已经更换了线路。

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

2 回答 2

3

NameMapper实现错误地假设拥有一个has_key()方法使Model类成为一个映射并尝试测试关键成员资格。

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

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

from collections import Mapping

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

它使用正确的抽象基类来检测映射对象。

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 没有包含在模型类文档中的一种便捷方法;它会FalseModel.key()方法 抛出NotSavedError异常时返回。

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

于 2014-08-16T09:06:28.290 回答
1

今天发布的 Cheetah3 (3.0.0) 包括NameMapper.py 函数的错误修复。

于 2017-05-07T20:52:32.777 回答