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:

      

+3


source to share


2 answers


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.

+3


source


Cheetah3 release today (3.0.0) includes a bugfix for NameMapper.py functions .



+1


source







All Articles