Google App Engine (python): filter users based on

2019-08-01 23:28发布

i am using the webapp2_extras.appengine.auth.models.User service which basically extends the google.appengine.api.users model. Now , I have custom users registered with my application and they have a lot of custom fields. The problem is i want to filter / (multi filter) all the users using various custom fields. For example:

the user model has 2 fields is_active and activation_key now i want to filter them using these fields, example:

from google.appengine.api import users

act_key = 'hw-2j38he63u83hd6hak3FshSqj3TGemn9'
user = users.all().filter('is_active =', False).filter('activation_key =', act_key).get()
if user:
  return True
else:
  return False

what are the best possible ways to filter on the user model using custom fields?

Edit:

Also tried the following:

from webapp2_extras.appengine.auth.models import User

query = User.query().filter('is_active =', False)
print query

but this raises an error as follows:

Traceback (most recent call last):
File "/opt/google_appengine_1.6.4/google/appengine/ext/admin/__init__.py", line 320, in post
exec(compiled_code, globals())
File "<string>", line 6, in <module>
File "lib/ndb/query.py", line 968, in filter
raise TypeError('Cannot filter a non-Node argument; received %r' % arg)
TypeError: Cannot filter a non-Node argument; received 'is_active ='

3条回答
smile是对你的礼貌
2楼-- · 2019-08-02 00:14

is your custom User Model implemented with the db package or ndb?

for the first question if you only need to check if a user exists or not you could make a keys_only query .all(keys_only=True).filter(...

the error you are getting in when querying with the webapp2 User model is depending on the ndb package. with ndb the right syntax for the query is:

User.query().filter(User.is_active == False) 

or

User.query(User.is_active == False)

of course you will need to query on the your custom User model.

查看更多
Explosion°爆炸
3楼-- · 2019-08-02 00:15

webapp2_extras.appengine.auth.models.User is an Expando model with created, updated, auth_ids and password properties. Everything beyond that or custom properties would be stored as an opaque blob, i.e., wouldn't be indexed. That said, one can't query/filter on them.

You could subclass the User model and add properties you need or (which is better) create a new model (say Account).

This is a good habit when dealing with the Datastore to keep your model as small as you can, and this is why: consider a model with dozens of properties, each time you fetch an entity you'd need to fetch them all; network isn't an issue here, what is, is protobuf decoding and Python is not really good at it.

查看更多
冷血范
4楼-- · 2019-08-02 00:23

The syntax for querying on Expando properties in NDB is a little different to how it's done in the old DB API, and is documented here. Your query needs to look something like this:

user = users.all().filter(ndb.GenericProperty('is_active') == False, ndb.GenericProperty('activation_key) == act_key).get()
查看更多
登录 后发表回答