AppEngine -> «AttributeError: объект« Юникод »не имеет атрибута« has_key »» при использовании хранилища BLOB-объектов - PullRequest
0 голосов
/ 31 октября 2010

Здесь был ряд других вопросов об 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 ]

2 голосов
/ 15 декабря 2011

Вы передаете o как значение other_item (в вашем примере кода вы называете его other, но я предполагаю, что это опечатка).o - это строка, извлеченная из запроса, и определение модели указывает, что это ReferenceProperty, поэтому он должен быть либо экземпляром класса Other, либо объектом db.Key.

Если предполагается, что o является строковым ключом, вместо десериализации введите db.Key(o).

Object действительно ужасное имя для класса хранилища данных (или любого другого класса)Кстати, базовый объект Python называется object, и это только одна заглавная буква - очень легко ошибиться.

1 голос
/ 11 декабря 2011

ошибка has_key вызвана ReferenceProperty other_items.Скорее всего, вы переходите в '' для других_элементов, когда API приложения ожидает диктат.Чтобы обойти это, вам нужно преобразовать other_items в хеш.

0 голосов
/ 31 октября 2010

[Предостережение, лектор: я знаю, о "google_app_engine"]

В сообщении указывается, что он ожидает dict (единственный известный объект, имеющий атрибут has_key) или аналогичный объекту, а не объект unicode, который вы указали. Возможно, вы должны проходить upload_file, а не upload_file.key() ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...