The AppEngine database model has a has_key () method but is not iterable?
What I get is: An argument of type "Lantern" is not repeated in one of the files in the template engine (Cheetah). As you might guess, the object is a lantern (see below).
NameWrapper.py:
if hasattr(obj, 'has_key') and key in obj:
This is a simplified version of my models. Nothing fancy, no additional methods just declare attributes.
models.py:
from google.appengine.ext import db
class Product(db.Model):
name = db.StringProperty(required=True)
class Lantern(Product):
height = db.IntegerProperty()
- How can I solve this problem?
- Is it correct that AppEngine models have a has_key function but are not iterable?
Solutions (edit):
I replaced the line.
if hasattr(obj, 'has_key') and isinstance(obj, collections.Iterable) and key in obj:
source to share
The implementation NameMapper
makes the erroneous assumption that the presence of a method has_key()
makes the class a Model
mapping and tries to check for key ownership.
This is a bug in Cheetah's implementation NameMapper
and should be reported to the project. You can try to disable functionality NameMapper
, the documentation suggests is optional and can be toggled with a compiler setting useNameMapper
. I'm not familiar with the syntax, but try not to rely on functionality in your templates.
If you'd like to edit Cheetah's code, you can replace the tests:
from collections import Mapping
if isinstance(obj, Mapping) and key in obj:
which uses the correct abstract base class to locate the mapping object.
Model
objects are not mappings. The function Model.has_key()
does not check for the existence of a mapping key, it is a method that checks if the object has a data store key.
The docstring for the method:
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.
"""
Note that the above method does not accept an argument other than an auto-bound one self
.
Model.has_key()
appears to be a convenient method that Google did not include in the Model Class Documentation ; it will return False
when the method Model.key()
will throw instead NotSavedError
.
In any case, objects Model
are not sequences; they have no method __iter__
and have no length indexing or support. As such, they are not iterable. Having a method has_key()
does not mean that they should be.
source to share