Search code examples
pythongoogle-app-enginegoogle-cloud-datastoreapp-engine-ndb

Datastore. Object attribute not found although it exists in the Datastore


An ndb.BooleanProperty(default=False) attribute is not found when the code performs a check on whether the user can perform an action.

I've tried using an ndb.StringProperty instead of the Boolean Property, but it makes no difference. Other attributes within the Property are recognised. Most interestingly, if I place a {{user.org_setup_done}} tag in jinja2 within the HTML, it returns correctly the value of the attribute, i.e. False.

In other words, I know the attribute is correctly created and stored within the User entity as I can see it in the datastore and call it with a jinja2 tag in the HTML. However when I perform a check on it it is not found.

class User(ndb.Model):
    """
    model for storing user information
    """
    email = ndb.StringProperty(required=True)  # the users email, as username
    pass_hash = ndb.StringProperty(required=True)  # the users hashed password
    org_setup_done = ndb.BooleanProperty(default=False)  # if the user has completed the org profile for creating events


class OrgCreateCompStartHandler(BaseHandler):
    """handler that lets you start creating an event by choosing series, date, name, start time and venue"""

    def get(self):
        try:
            user = self.user_obj()  # get the user object from session, returns None if no session exists

            if user.org_setup_done:  # check to see if the user is org_ready. If yes, continue with the event creation,
                # if no then redirect to the profile page for event organisers.
                # : TEMPLATE VALUES
                template_values = {
                    'user': user,
                }
                # : RENDER TEMPLATE
                self.render_template(ROUTE, 'org-create.html', template_values)

            else:
                self.redirect("/")

        except Exception, e:
            logging.error("ERROR is %s" % e)
            logging.exception("EXC is %s" % e)
            self.redirect("/oops")  # unexpected error

Expected Result should be for the org-create.html page to render after the code checks that the org_setup_done attribute is True.

Actual Result is the following error:

Traceback (most recent call last):
  File "C:\Users\events.py", line 2433, in get
    if user.org_setup_done:  
AttributeError: 'User' object has no attribute 'org_setup_done'

Does anyone have any idea on this? I'm truly confused by this one.


Solution

  • user = self.user_obj()  # get the user object from session, returns None if no session exists
    

    I think your User model is clashing with the built-in User model from webapp2

    You could config webapp2 to use your User model

    webapp_app = webapp2.WSGIApplication(
    config={
        ...
        'webapp2_extras.auth': {'user_model': 'path.to.my.user_model_file.User'},
    })
    

    However webapp2's session code probably has some assumptions about what fields / functions the User object has, so you'd need to implement those in your User. You could also just have your User model inherit the webapp2 one

    from webapp2_extras.appengine.auth.models import User as _webapp2_User
    
    class User(_webapp2_User):
        ...