0

All,

I am in the process of learning Google App Engine / Webapp2 and i'm having trouble saving an object to the datastore, redirecting to another page/handler, then fetching that object from the datastore. Forgive me if there is an easy answer to this question. The following is a description of the code I have.

I have a base handler:

    class BaseHandler(webapp2.RequestHandler):

    def set_secure_cookie(self, name, val):
        cookie_val = make_secure_val(val)
        self.response.headers.add_header(
            'Set-Cookie', 
            '%s=%s; Path=/' % (name, cookie_val))

    def get_secure_cookie(self, name):
        cookie_val = self.request.cookies.get(name)
        return cookie_val and check_secure_val(cookie_val)

    def login(self, user):
        self.set_secure_cookie('user', str(user.name))

    # Called before every request and stores user object
    def initialize(self, *a, **kw):
        webapp2.RequestHandler.initialize(self, *a, **kw)
        username = self.get_secure_cookie('user')
        self.user = username and User.by_name(str(username))

I have a Signup page which inherits from BaseHandler:

class Signup(BaseHandler):
    def get(self):
        # Get the page

    def post(self):
        has_error = False

    # Extract and validate the input

        if has_error:
            #Re-render the form

        else:
            new_user = User.register(self.username, self.password, self.email)

            new_user.put()
            self.login(new_user)

            self.redirect("/blog/welcome")

If the user is a new user, the User db.Model object is created, the user is stored to the datastore, a user cookie is set and we are redirected to the Welcome handler:

class Welcome(BaseHandler):
    def get(self):
        if self.user:
            self.render('welcome.html', username = self.user.name)
        else:
            self.redirect('/blog/signup')

The intent here is that upon redirect, BaseHandler.initialize() would get called and would set self.user of the new user I just created.

Here is what I know:
- When signing up a new user, I am redirected back to the signup page.
- If I then manually navigate to /blog/welcome, the page loads correctly with the new username populated.

If I add the following logging statements into Welcome.get():

username = self.get_secure_cookie('user')
logging.info("Cookie %r obtained inside of Welcome.get().", username)
logging.info("Found user %r", User.by_name(str(username)))

The cookie is obtained for the new username but no User object is found. Again, if I navigate directly to /blog/welcome, the logs report that the cookie is obtained and the User object is found for the new user.

The User object looks like so:

def users_key(group = 'default'):
    return db.Key.from_path('users', group)

class User(db.Model):
    name = db.StringProperty(required = True)
    password = db.StringProperty(required = True)
    email = db.StringProperty()

    @classmethod
    def by_name(cls, name):
        u = User.all().filter('name =', name).get()
        return u

    @classmethod
    def register(cls, name, password, email = None):
    return User(parent = users_key(),
                name = name,
                password = password,
                email = email)

Is there something about the datastore that is causing this first query to get the new user to return nothing? How should I proceed in debugging this? Is there additional reading I should do? (I have tried to provide all necessary code snippets but I can provide additional code if required.)

4

1 回答 1

2

只是猜测,但我怀疑您的 RequestHandler 中的 self.username、self.password 和 self.email 没有设置为任何内容。我假设您从请求 POST 数据中获取这些参数,但这在显示的代码中没有发生。

另一个潜在问题是您的查询最终是一致的,并且可能无法反映最近的更改(即新的用户实体)。如果您通过 get() 调用而不是通过 filter() 查询来获取用户的 key 或 id,那会好得多。

于 2013-08-28T02:55:20.723 回答