I'm trying to define a model whose id
is case-insensitive but case-preserving, and the below nearly works:
class MyModel(endpoints_ndb.EndpointsModel):
_message_fields_schema = ('id', 'name')
caseful_id = ndb.StringProperty(indexed=False)
name = ndb.StringProperty(required=True)
def IdSet(self, value):
if not isinstance(value, basestring):
raise TypeError('ID must be a string.')
self.caseful_id = value
self.UpdateFromKey(ndb.Key(self.__class__, value.lower()))
@endpoints_ndb.EndpointsAliasProperty(setter=IdSet)
def id(self):
return self.caseful_id
Creating a new instance stores the id
in lowercase, with the original capitalisation in caseful_id
, and fetching a list returns the original capitalisations, but requesting a specific model by id
with:
@MyModel.method(request_fields=('id',), path='mymodel/{id}',
http_method='GET', name='mymodel.get')
def MyModelGet(self, mymodel):
if not mymodel.from_datastore:
raise endpoints.NotFoundException('MyModel not found.')
return mymodel
always returns the same id
that was given in the request, with the same capitalisation. Is there a way to make it actually call the id
getter function?
Your setter is being called, and it is causing the behavior you don't want. Tearing it down:
def IdSet(self, value):
if not isinstance(value, basestring):
raise TypeError('ID must be a string.')
self.caseful_id = value
self.UpdateFromKey(ndb.Key(self.__class__, value.lower()))
since you call
self.caseful_id = value
before UpdateFromKey
, the caseful_id
will always be the one from the most recent request.
Bear in mind that UpdateFromKey
tries to retrieve an entity by that key and then patches in any missing data from the entity stored in the datastore (and also sets from_datastore
to True
).
Since you set the caseful_id
field before UpdateFromKey
, there is no missing data. Instead, you could do this to set the value if not already set (and so this wouldn't be relevant for your 'GET'
method):
def IdSet(self, value):
if not isinstance(value, basestring):
raise TypeError('ID must be a string.')
self.UpdateFromKey(ndb.Key(self.__class__, value.lower()))
if self.caseful_id is None:
self.caseful_id = value