Search code examples
pythongoogle-app-enginegoogle-cloud-datastoreapp-engine-ndb

How do I filter a dict to match the attributes of my ndb.Model subclass


I have some simple models:

class MyModel1(ndb.Model):
    attribute1 = ndb.StringProperty()
    attribute2 = ndb.StringProperty()

class MyModel2(MyModel1):
    attribute3 = ndb.StringProperty()
    attribute4 = ndb.StringProperty()

And I have an api that provides a json dict to a RequestHandler:

class APIRequestHandler(webapp2.RequestHandler):
    def dispatch(self):
        if len(self.request.body) > 0:
            self.request.jsondata = json.loads(self.request.body)
        super(APIRequestHandler, self).dispatch()

And I have some concrete subclasses that support PUT:

class MyModel1Handler(APIRequestHandler):

    def put(self, key):
        mymodel1 = get_model(key)
        mymodel1.populate(**self.request.jsondata)
        mymodel1.put()
#write the response

class MyModel2Handler(APIRequestHandler):

    def put(self, key):
        mymodel2 = get_model(key)
        mymodel2.populate(**self.request.jsondata)
        mymodel2.put()
#write the response

However, I'd like to filter the dict self.request.jsondata when calling populate removing any keys that are not attributes on the objects. Is there a simple pythonic way of doing this?


Solution

  • Get a list of the model's properties using a list comprehension

    filter_props = [k for k, v in Model1._properties.iteritems()]
    

    Filter original dict by these property names using a dict comprehension

    new_dict = {k:v for (k, v) in self.request.jsondata.iteritems() if k in filter_props}
    

    Use this new dict to populate the model

    mymodel1.populate(**new_dict)
    

    This is about as clean as it gets, there is no special NDB functionality to do this