AppEngine - >使用blobstore时,“AttributeError:'unicode'对象没有属性'has_key'”

时间:2010-10-30 21:51:32

标签: python google-app-engine blobstore

这里有关于AttributeErrors的其他一些问题,但是我已经阅读了它们,但我仍然不确定在我的特定情况下导致类型不匹配的原因。

提前感谢您对此的任何想法。

我的模特:

class Object(db.Model):
  notes = db.StringProperty(multiline=False)
  other_item = db.ReferenceProperty(Other)
  time = db.DateTimeProperty(auto_now_add=True)
  new_files = blobstore.BlobReferenceProperty(required=True)
  email = db.EmailProperty()
  is_purple = db.BooleanProperty()

我的BlobstoreUploadHandler:

class FormUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
  def post(self):
    try:
      note = self.request.get('notes')
      email_addr = self.request.get('email')
      o = self.request.get('other')
      upload_file = self.get_uploads()[0]

      # Save the object record
      new_object = Object(notes=note,
           other=o,
           email=email_addr,
           is_purple=False,
           new_files=upload_file.key())

      db.put(new_object)

      # Redirect to let user know everything's peachy.
      self.redirect('/upload_success.html')

    except:
      self.redirect('/upload_failure.html')

每次我提交上传文件的表单时,都会抛出以下异常:

ERROR    2010-10-30 21:31:01,045 __init__.py:391] 'unicode' object has no attribute 'has_key'
Traceback (most recent call last):
  File "/home/user/Public/dir/google_appengine/google/appengine/ext/webapp/__init__.py", line 513, in __call__
    handler.post(*groups)
  File "/home/user/Public/dir/myapp/myapp.py", line 187, in post
    new_files=upload_file.key())
  File "/home/user/Public/dir/google_appengine/google/appengine/ext/db/__init__.py", line 813, in __init__
    prop.__set__(self, value)
  File "/home/user/Public/dir/google_appengine/google/appengine/ext/db/__init__.py", line 3216, in __set__
    value = self.validate(value)
  File "/home/user/Public/dir/google_appengine/google/appengine/ext/db/__init__.py", line 3246, in validate
    if value is not None and not value.has_key():
AttributeError: 'unicode' object has no attribute 'has_key'

最让我感到困惑的是,这段代码几乎完全脱离了文档,并且还提供了blob上传处理程序的其他示例,我也在教程中在线找到了。

我运行了--clear-datastore以确保我对数据库模式所做的任何更改都不会导致问题,并尝试将upload_file作为各种事情进行转换,以确定是否会安抚Python - 关于我搞砸的任何想法?


编辑:我找到了一种解决方法,但它不是最理想的。

将UploadHandler更改为此可解决此问题:

  ...
  # Save the object record
  new_object = Object()

  new_object.notes = note
  new_object.other = o
  new_object.email = email.addr
  new_object.is_purple = False
  new_object.new_files = upload_file.key()

  db.put(new_object)
  ...

我注意到注释掉文件行后为other行引发了同样的问题,我做了这个转换,依此类推。但这不是最佳解决方案,因为我无法以这种方式强制执行验证(在模型中,如果我根据需要设置任何内容,我不能在不抛出异常的情况下声明上面的空实体)。

为什么我不能宣布实体并同时填充它的任何想法?

3 个答案:

答案 0 :(得分:2)

您传递o作为other_item的值(在您的示例代码中,您称之为other,但我认为这是一个错字)。 o是从请求中获取的字符串,模型定义指定它是ReferenceProperty,因此它应该是Other类的实例,或{{1}对象。

如果db.Key应该是字符串化的密钥,请传入o,然后反序列化。

对于数据存储类(或者任何类,实际上)来说,

db.Key(o)是一个非常可怕的名称,顺便说一句,Python基础对象被称为Object,而且这只是一个大写字母 - 非常容易出错。

答案 1 :(得分:1)

has_key错误是由于ReferenceProperty other_items造成的。当appengine的api期望一个字典时,你最有可能传入''for other_items。为了解决这个问题,您需要将other_items转换为hash。

答案 2 :(得分:0)

[告诫者:我知道zilch关于“google_app_engine”]

该消息表明它期望dict(唯一具有has_key属性的已知对象)或类似工作的对象,而不是您提供的unicode对象。也许你应该通过upload_file,而不是upload_file.key() ......