User
から継承するカスタムモデルであると想定していEndpointsModel
ます。そうでない場合、これは失敗します。つまり、次のようなことを行いました。
from google.appengine.ext import ndb
from endpoints_proto_datastore.ndb import EndpointsModel
class User(EndpointsModel):
email = ndb.StringProperty()
...
この問題を解決するには、主に 2 つの方法がありますemail
。エンティティのキーとして を使用するか、独自のクエリをロールして 2 つのエンティティをフェッチして、結果が一意で存在するかどうかを確認します。
オプション 1:email
キーとして使用
完全なクエリを実行する代わりに、単純な getを実行できます。
from google.appengine.ext import endpoints
@endpoints.api(...)
class SomeClass(...):
@User.method(request_fields=('email',),
path='get_by_mail/{email}',
http_method='GET', name='user.get_by_email')
def get_by_email(self, user):
if not user.from_datastore:
raise endpoints.NotFoundException('User not found.')
return user
カスタム エイリアス プロパティのサンプルで行われているように、電子メールを各エンティティのデータストア キーとして使用します。例えば:
from endpoints_proto_datastore.ndb import EndpointsAliasProperty
class User(EndpointsModel):
# remove email here, as it will be an alias property
...
def EmailSet(self, value):
# Validate the value any way you like
self.UpdateFromKey(ndb.Key(User, value))
@EndpointsAliasProperty(setter=IdSet, required=True)
def email(self):
if self.key is not None: return self.key.string_id()
オプション 2: 独自のクエリを展開する
@User.method(request_fields=('email',),
path='get_by_mail/{email}',
http_method='GET', name='user.get_by_email')
def get_by_email(self, user):
query = User.query(User.email == user.email)
# We fetch 2 to make sure we have
matched_users = query.fetch(2)
if len(matched_users == 0):
raise endpoints.NotFoundException('User not found.')
elif len(matched_users == 2):
raise endpoints.BadRequestException('User not unique.')
else:
return matched_users[0]