我有带有验证器的模型User
和属性,用于验证数据库中的可用字符、非空字符和存在。因此,例如,在处理注册表单时,我不需要任何其他检查 - 我只需将表单的值分配给模型的属性并捕获验证错误(如果输入已经存在)...username
username
username
username
但是,这行不通。
因为 NDB 也验证了属性的比较参数(请参阅 ndb/model.py 中的 Property._comparison 方法),并且它在 Query.filter(User.username == [somevalue]) 中进行无休止的请求,最后引发RuntimeError: maximum recursion depth exceeded
. NDB 尝试验证 [somevalue]validate_username
并一次又一次地转到此查询...
可以将用户名分配给实体的 ID 并使用 User.get_by_id(),但它需要username
是可更改的,所以我需要使用Query.get()
.
所以这是我的User
模型:
class User(ndb.Model):
def validate_username(self, value):
value = str(value).strip()
# Other useful checks - length, available symbols, etc
if User.get_user(value):
raise ValueError('Username already exists')
return value
@classmethod
def get_user(cls, username):
username = str(username)
user_q = User.query()
user_q = user_q.filter(User.username == username) # Here is the problem
return user_q.get()
username = ndb.StringProperty(validator=validate_username)
例如:
# Trying to add user, get RuntimeError exception
u = User()
u.username = 'John'
我做错了什么?解决此类问题的最佳方法是什么?
更新到蒂姆霍夫曼:
谢谢。是的,我错过了 prop 参数,但是在参数prop
中self
和参数中收到了方法 - 因此我没有提到这个错误。但是,您错过了关键问题 - 您没有在验证器中使用带有过滤器的查询(User.get_user 方法)。试试这个,没有感觉函数或方法验证器是:val
val
def validate_username2(prop, value):
if User.get_user(value):
raise Exception('User exists!')
return value
class User(ndb.Model):
def validate_username(self, value):
if User.get_user(value):
raise Exception('User exists!')
return value
@classmethod
def get_user(self, username):
user_q = User.query()
user_q = user_q.filter(User.username == username)
return user_q.get()
# Try both please
username = ndb.StringProperty(validator=validate_username)
#username = ndb.StringProperty(validator=validate_username2)