简体   繁体   中英

BadKeyError when posting keys from an HTML form

I'm trying to make a function in my app in which a user can associate a current location with their account. Users can add several Locations, and when a Location is added it is added as a child of that User. To allow the user to set their current location, I have created a form in which they specify which location they want to set as their current location. The template for this is as follows:

<form action="setlocation" method="post">
<table id="locationform" class="fitted">
    <tr>
        <td colspan="3"><b>Location settings</b></td>
    </tr>
    <tr>
        <td class="label">Current location</td>
        <td class="input">
            <select name="lockey">
                {% for i in locinfo %}
                    <option value="{{i.key}}">{{i.locname}}</option>
                {% endfor %}
            </select>
        </td>
        <td><input type="submit" value="Set Location"></td>
    </tr>
    <tr>
        <td colspan="3"><a href="/addlocation">Add new location</a></td>
    </tr>
</table>
</form>

So the value of each selection is the key for that location. The form posts to /setlocation, which is handled like this:

class SetLocation(BaseHandler):
    def post_secure(self):
        userdata = db.GqlQuery("SELECT * FROM User WHERE fbid = :1", self.user['uid'])[0]
        userdata.currentloc = self.request.get('lockey')
        logging.warn("Current location saved")
        userdata.put()
        self.redirect('/account')

...however when I go to the datastore there is no value associated with currentloc. In the handler for /account I have put a line to log the key of the user's currentloc, and get an error in the log saying "BadKeyError: Cannot string encode an incomplete key!". I can't see where the key has been changed along the way so I guess it's something to do with the conversion between strings (for the page) and the db.Key() type.

EDIT

This is the complete stack trace of the error:

Traceback (most recent call last): File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/logging/ init .py", line 744, in emit msg = self.format(record) File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/logging/ init .py", line 630, in format return fmt.format(record) File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/logging/ init .py", line 418, in format record.message = record.getMessage() File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/logging/ init .py", line 288, in getMessage msg = msg % self.args File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore_types.py", line 595, in str 'Cannot string encode an incomplete key!\\n%s' % self.__reference) BadKeyError: Cannot string encode an incomplete key!

You need to include the complete stacktrace and the code where it includes to be certain, but it sounds like you're getting the exception when generating the form, not when submitting it.

The exception you're referring to occurs if you fetch the .key() from an object and attempt to call str() on it, when you have not specified a key name, and haven't yet stored the entity to the datastore. Call .put() on the entity before attempting to stringify the key.

Solved it. The problem was I was storing the reference to the current location as the db.Key type rather than db.ReferenceProperty.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM