我想问一下它是什么意思“AttributeError:'unicode'对象没有属性'has_key'” 这是完整的堆栈跟踪:
Traceback (most recent call last):
File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\webapp\__init__.py", line 509, in __call__
handler.post(*groups)
File "D:\Projects\workspace\foo\src\homepage.py", line 71, in post
country=postedcountry
File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\db\__init__.py", line 656, in __init__
prop.__set__(self, value)
File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\db\__init__.py", line 2712, in __set__
value = self.validate(value)
File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\db\__init__.py", line 2742, in validate
if value is not None and not value.has_key():
AttributeError: 'unicode' object has no attribute 'has_key'
让我再详细介绍一下情况:
首先,我创建了models.py,其中包含用于CMSRequest的db.Model,其具有引用CMSCountry类的属性country
class CMSRequest(db.Model):
country = db.ReferenceProperty(CMSCountry, required=True)
class CMSCountry(db.Model):
name = db.StringProperty(required=True)
然后,我创建了一个bulkloader类来将数据导入CMSCountry
在表单中,用户可以从下拉列表框中选择国家/地区,结果将被回发并保存到CMSRequest对象
def post(self):
postedcountry = self.request.get('country')
cmsRequest = models.CMSRequest(postedcountry)
也许我找到了我的问题的解决方案,这是因为我没有将CMSCountry的已发布密钥转换回保存到CMSRequest。
谢谢大家!
答案 0 :(得分:6)
在这一行:
if value is not None and not value.has_key():
value
是一个unicode字符串。看起来代码期望它是db.Model
,
(从我所看到的,has_key
是db.Model
的方法,以及Python字典的方法,但这必须是db.Model
,因为它被调用没有争论。)
您是否将字符串传递给期望db.Model
?
答案 1 :(得分:3)
您的问题是,postedcountry是一个字符串而不是国家/地区对象。从self.request.get检索的值是浏览器传递的变量的字符串值。
您需要使用某些GQL查找国家/地区对象。具体如何操作将取决于HTML表单的国家/地区字段的确切位置,对象密钥?,国家/地区名称?
def post(self):
postedcountry = self.request.get('country')
# <-------- Need to look up a country here !!!!!
cmsRequest = models.CMSRequest(country=postedcountry)
答案 2 :(得分:2)
注意:通常在Python中使用“映射”类型(字典和类似字典......例如各种类型的dbm(索引文件)和一些DBMS / ORM接口......)将实现has_key()
方法。
当你期望有某种字典或其他映射对象引用时,你已经在这个语句中得到了一个Unicode(字符串)对象。
一般来说, AttributeError 意味着您已经纠结了对象绑定(变量赋值)。除了你想要的类型之外,你给某个对象命名了。 (或者有时它意味着你有一个像“.haskey()”而不是has_key()
等等的错字。)
has_key()
有点过时了。通常情况下,最好使用Python in
运算符(隐式调用__contains__()
}来测试容器,这些运算符适用于列表,字符串和其他序列以及映射类型)。
即使value.has_key()
是字典,value
也会引发错误,因为.has_key()
方法需要参数。
在您的代码中,我会明确地测试if postedcountry is not None:
...或者我会为.get()
提供“postscountry”的(可选)默认值。
您希望如何处理request
没有 postedcountry 的情况?你想假设它是从某个特定的默认值发布的吗?强制重定向到某个页面,要求用户为该表单元素提供值?提醒西班牙宗教裁判所?
答案 3 :(得分:1)
如果您阅读了追溯,它会告诉您到底发生了什么:
if value is not None and not value.has_key():
AttributeError: 'unicode' object has no attribute 'has_key'
这说明您使用的value
变量没有has_key
属性。并且,它告诉你的是你的value
变量不是字典,因为它看起来像你期待的......相反,它是一个unicode对象,它基本上是一个字符串。
答案 4 :(得分:1)
您正在尝试将字符串设置为ReferenceProperty。 CMSCountry的“country”字段是db.ReferenceProperty,它接受db.Key或CMSCountry对象,但您尝试将其设置为字符串。
你应该这样做:
def post(self):
postedcountry = self.request.get('country')
country = models.CMSCountry.all().filter('name =', postedcountry)
if not country:
# Couldn't find the country
else:
cmsRequest = models.CMSRequest(country=country)
但是请对file a bug做一些相当无用的错误消息。
答案 5 :(得分:0)
字典对象的has_key()方法在3.0中已弃用 - 请改用“in”表达式。如果您在3.x中使用旧库,则必须更改代码以适应它。