Как отфильтровать по ComputedProperty в query_method?
Как сделать один запрос для вычисляемых свойств?
class MyModel(EndpointsModel):
attr1 = ndb.IntegerProperty(default=0)
@EndpointsComputedProperty(property_type=messages.BooleanField)
def attr2(self):
return self.attr1 % 2 == 1
@endpoints.api(name='myapi', version='v1', description='My Little API')
class MyApi(remote.Service):
@MyModel.query_method(query_fields=('attr2'),
path='mymodels', name='mymodel.list')
def MyModelList(self, query):
return query
В этом случае query
всегда будет иметь фильтр, который будет проверять attr2 == False
,
Причина в том, что фильтры создаются из сущности, созданной с FromMessage
, Как attr2
является вычисляемым свойством, его нельзя установить. Как attr1
по умолчанию 0, attr2
всегда False независимо от того, что передается.
1 ответ
Вы можете запросить вычисленные свойства, настроив свойство псевдонима-заполнителя, аналогичное тому, как можно выполнять запросы неравенства, как описано здесь: /questions/34363914/konechnaya-tochka-proto-datastore-filtr-neravenstva-dlya-metoda-querymethod/34363924#34363924
В частности, мы установили свойство псевдонима с именем, отличным от наших существующих полей attr1 и attr2. Мы также определяем установщик, который вызывается всякий раз, когда назначается свойство псевдонима, и используем этот установщик для изменения запроса. Обратите внимание, что сеттер должен появляться над свойством псевдонима:
import logging
from google.appengine.ext import ndb
from endpoints_proto_datastore.ndb import EndpointsModel
from endpoints_proto_datastore.ndb.properties import EndpointsAliasProperty
from endpoints_proto_datastore.ndb.properties import EndpointsComputedProperty
from protorpc import messages
class MyModel(EndpointsModel):
attr1 = ndb.IntegerProperty(default=0)
@EndpointsComputedProperty(property_type=messages.BooleanField)
def attr2(self):
return self.attr1 % 2 == 1
def Attr2AliasSetter(self, value):
self._endpoints_query_info._filters.add(MyModel.attr2 == value)
@EndpointsAliasProperty(name='attr2_alias',
property_type=messages.BooleanField,
setter=Attr2AliasSetter)
def Attr2Alias(self):
logging.error('attr2_alias should never be accessed')
Затем мы обновляем update_method, чтобы принять поле attr2_alias, а не attr2:
@endpoints.api(name='myapi', version='v1', description='My Little API')
class MyApi(remote.Service):
@MyModel.query_method(query_fields=('attr2_alias'),
path='mymodels', name='mymodel.list')
def MyModelList(self, query):
return query
Затем, например, запросить myapi/mymodels?attr2_alias=true
вернет все сущности MyModel с attr2, установленным в true.