Как отфильтровать по 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.

Другие вопросы по тегам