问题
When using the endpoints-proto-datastore query_method on an EndpointsModel, is it possible to have an inequality filter passed as a query field?
For instance, say I have a model with a lastmodified
field, and I want to query for all the records that have a lastmodified > date
, where date is a value passed to the API by the client.
class MyModel(EndpointsModel):
attr1 = ndb.StringProperty()
lastmodified = ndb.DateTimeProperty()
From the documentation I have seen, it seems like the query_fields is strictly an equality filter.
回答1:
Yes, but you'll need to use an EndpointsAliasProperty
with a name different than the lastmodified
field. For example, you could do something like was done in the Picturesque app used as a sample at Google I/O 2013.
First, define your model
from google.appengine.ext import ndb
from endpoints_proto_datastore.ndb import EndpointsModel
class MyModel(EndpointsModel):
attr1 = ndb.StringProperty()
lastmodified = ndb.DateTimeProperty()
then create an alias property which will be used to update the query
from google.appengine.ext import endpoints
from endpoints_proto_datastore.ndb import EndpointsAliasProperty
...
@EndpointsAliasProperty(name='modifiedSince', setter=ModifiedSinceSet)
def ModifiedSince(self):
raise endpoints.BadRequestException(
'modifiedSince value should never be accessed.')
This property won't ever be accessed, but its setter is relevant to make the query sort on what we want, so we need to define ModifiedSinceSet
(it needs to come before the variable is reference, as in the sample):
import datetime
from endpoints_proto_datastore import utils
...
def ModifiedSinceSet(self, value):
try:
modified_since = utils.DatetimeValueFromString(value)
if not isinstance(modified_since, datetime.datetime):
raise TypeError('Not a datetime stamp.')
except TypeError:
raise endpoints.BadRequestException('Invalid timestamp for modifiedSince.')
self._endpoints_query_info._filters.add(
MyModel.lastmodified >= modified_since)
Here we convert the passed in value (from the request) to a datetime.datetime
object and then use it to add a filter to self._endpoints_query_info._filters
on the current EndpointsModel
object.
This _endpoints_query_info
is of course used in query_method to create the query that gets passed to your method.
Another alternative:
You could just parse the value and use introduce your own syntax. For example, accept strings like lastmodified>=TIMESTAMP
and then parse the timestamp from the statement.
来源:https://stackoverflow.com/questions/17288681/endpoints-proto-datastore-inequality-filter-on-query-method