在实例化我的自定义用户类时获取 ndb 断言错误



我在尝试实例化我的用户模型时收到断言错误。在下面的堆栈跟踪中,我省略了将请求调度到请求处理程序。

File "/Users/frederikcreemers/jsbeast/users.py", line 68, in get
    User(nickname=nickname,user=users.get_current_user()).put()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2926, in _put
    return self._put_async(**ctx_options).get_result()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 322, in get_result
    self.check_success()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 317, in check_success
    self.wait()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 301, in wait
    if not ev.run1():
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/eventloop.py", line 219, in run1
    delay = self.run0()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/eventloop.py", line 181, in run0
    callback(*args, **kwds)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/context.py", line 170, in _finished_callback
    fut.check_success()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 362, in _help_tasklet_along
    value = gen.send(val)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/context.py", line 268, in _put_tasklet
    keys = yield self._conn.async_put(options, datastore_entities)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1550, in async_put
    pbs = [self.__adapter.entity_to_pb(entity) for entity in entities]
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 548, in entity_to_pb
    pb = ent._to_pb()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2719, in _to_pb
    prop._serialize(self, pb)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 1245, in _serialize
    values = self._get_base_value_unwrapped_as_list(entity)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 1034, in _get_base_value_unwrapped_as_list
    wrapped = self._get_base_value(entity)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 1022, in _get_base_value
    return self._apply_to_values(entity, self._opt_call_to_base_type)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 1186, in _apply_to_values
    newvalue = function(value)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 1065, in _opt_call_to_base_type
    value = _BaseValue(self._call_to_base_type(value))
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 599, in __init__
    assert not isinstance(b_val, list), repr(b_val)
AssertionError: []

发生这种情况的代码如下所示:

class LoginHandler(webapp2.RequestHandler):
    def get(self):
        url = self.request.get('url')
        if not url:
            url = "/"
        if User.current():
            self.redirect(url)
        else:
            if users.get_current_user():
                nickname = self.request.get("nickname")
                if(not nickname):
                    self.response.out.write(views.render("nickname"))
                    return
                else:
                    errors = []
                    if len(nickname) < 3:
                        errors.append("Your nickname should be at least 3 characters long.")
                    if(len(nickname) > 15):
                        errors.append("Your nickname should not be longer than 15 characters.")
                    import re
                    if not re.match(r"[0-9a-zA-Z_.]+$",nickname):
                        errors.append("Your nickname can only contain small and capital letters, numbers, underscores and dots.")
                    if len(errors) == 0 and User.by_nickname(nickname):
                        errors.append("The name "+nickname+" is already in use.")

                    if len(errors) == 0:
                        import logging
                        User(nickname=nickname,user=users.get_current_user()).put()
                        self.redirect(url)
                    else:
                        self.response.out.write(views.render('nickname',{'errors':errors}))
                        return
            else:
                self.redirect(users.create_login_url("/user/login",federated_identity=self.request.get('provider')))

请注意,尽管我导入google.appengine.api.users但该模块中的用户 objecvt 仍保存在 users 命名空间中,因此不会存在冲突。

这是用户模型的样子:

class User(ndb.Model):
nickname = ndb.StringProperty()
email = ndb.StringProperty()
user = ndb.UserProperty()
num_solved_problems = ndb.ComputedProperty(lambda self: problems.Attempt.query().filter(problems.Attempt.user == self.user,problems.Attempt.correct == True).count())
solved_problems = ndb.ComputedProperty(lambda self:problems.Attempt.query().filter(problems.Attempt.user == self.user,problems.Attempt.correct == True).fetch())
@classmethod
def current(cls):
    if not users.get_current_user():
        return None
    return cls.query().filter(User.user == users.get_current_user()).get()
@classmethod
def by_nickname(cls,nickname):
        return cls.query().filter(User.nickname == nickname).get()

我的猜测是 ComputedProperty solved_problems需要说 repeated=True,因为 fetch() 返回了一个列表。

附言。不是你的错,但是当SO坚持显示水平滚动条时,很难阅读代码示例。

最新更新