Search code examples
pythongoogle-app-engineintrospection

Define field in ndb using strings


This is my code:

class SocialNodeSubscription(model.Model):
  def __init__(self, *args, **kwargs):
    permissions=["post","read","reply","admin"]
    for p in permissions:
      self.__dict__["can_"+p]=model.BooleanProperty(default=True)        

I need to dynamically define fields in my model but this doesn't seem to work because dict is not the right place where to put my fields.

For who don't know about ndb, this is how it would look like going the easier way.

class SocialNodeSubscription(model.Model):
  def __init__(self, *args, **kwargs):
    self.can_write=model.BooleanProperty(default=True)
    self.can_read=model.BooleanProperty(default=True)
      ...

Edit:

Now my code looks like this:

def __init__(self, *args, **kwargs):
    permissions=["post","read","reply","admin"]

    for p in permissions:
        self._properties["can_"+p]=model.BooleanProperty(default=True)        
     self._fix_up_properties()

But still i get this error.

File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\ndb\model.py", line 972, in _store_value entity._values[self._name] = value TypeError: 'NoneType' object does not support item assignment

What does it mean?


Solution

  • It's _properties, just have a look at its metaclass MetaModel and class method _fix_up_properties.

    Definition of _properties:

     # Class variables updated by _fix_up_properties()
     _properties = None
    

    Method:

      @classmethod
      def _fix_up_properties(cls):
      """Fix up the properties by calling their _fix_up() method.
    
      Note: This is called by MetaModel, but may also be called manually
      after dynamically updating a model class.
      """