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 ='
is your custom User Model implemented with the
db
package orndb
?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:
or
of course you will need to query on the your custom User model.
webapp2_extras.appengine.auth.models.User
is an Expando model withcreated
,updated
,auth_ids
andpassword
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 (sayAccount
).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.
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: