从 HTML 表单发布密钥时出现 BadKeyError
我正在尝试在我的应用程序中创建一个功能,用户可以将当前位置与其帐户相关联。用户可以添加多个位置,并且当添加位置时,它将被添加为该用户的子级。为了允许用户设置其当前位置,我创建了一个表单,用户可以在其中指定要设置为当前位置的位置。其模板如下:
<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>
因此,每个选择的值都是该位置的键。表单发布到 /setlocation,处理方式如下:
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')
...但是,当我转到数据存储时,没有与 currentloc 关联的值。在 /account 的处理程序中,我放置了一行来记录用户 currentloc 的密钥,并在日志中收到一条错误消息“BadKeyError:无法对不完整的密钥进行字符串编码!”。我看不到密钥在哪里发生了变化,所以我猜这与字符串(页面)和 db.Key() 类型之间的转换有关。
编辑
这是错误的完整堆栈跟踪:
回溯(最近一次调用最后一次): 文件“/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/logging/init.py”,第 744 行,在发射中 msg = self.format(记录) 文件“/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/logging/init.py”,第 630 行,格式 返回 fmt.format(记录) 文件“/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/logging/init.py”,第 418 行,格式 记录.message = 记录.getMessage() 文件“/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/logging/init.py”,第 288 行,在 getMessage 中 味精 = 味精 % self.args 文件“/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore_types.py”,第 595 行,位于 str 中 '无法对不完整的密钥进行字符串编码!\n%s' % self.__reference) BadKeyError:无法对不完整的密钥进行字符串编码!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要包含完整的堆栈跟踪及其包含的代码才能确定,但听起来您在生成表单时遇到异常,而不是在提交表单时遇到异常。
如果您在未指定密钥的情况下从对象中获取
.key()
并尝试对其调用str()
,则会发生您所指的异常名称,并且尚未将实体存储到数据存储中。在尝试对键进行字符串化之前,对实体调用.put()
。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 callstr()
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.解决了。问题是我将对当前位置的引用存储为 db.Key 类型而不是 db.ReferenceProperty。
Solved it. The problem was I was storing the reference to the current location as the db.Key type rather than db.ReferenceProperty.