1

在遇到错误

BadValueError: Virtual property is read-only

我在文档中没有找到有关此错误的任何内容。这是什么意思?这是代码的相关部分。它一直有效,直到最近的 SDK 更新。

date = dt.datetime.strptime(self.json['birthday'],"%Y-%m-%d").date()
if self.json.has_key('avatar'):
    img = base64.b64decode(self.json['avatar'])
else:
    img = None
    log.info('No avatar')
user = db.User(
    name=self.json['name'], 
    password=self.json['password'], 
    full_name=self.json['full_name'],
    email = self.json['email'],
    birthday = date,
    avatar = img)
user.put()

服务器日志

  File "/api/tornado/web.py", line 1064, in _execute
    getattr(self, self.request.method.lower())(*args, **kwargs)
  File "user.py", line 31, in post
    avatar = img)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/db/__init__.py", line 970, in __init__
    prop.__set__(self, value)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/db/__init__.py", line 615, in __set__
    setattr(model_instance, self._attr_name(), value)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/db/__init__.py", line 3874, in __set__
    raise BadValueError('Virtual property is read-only')
BadValueError: Virtual property is read-only
INFO     2013-06-08 07:44:37,776 server.py:585] default: "POST /api/user/create HTTP/1.1" 500 93

数据库模型

class User(db.Model):
    name = db.StringProperty(required=True)
    password = db.StringProperty(required=True)
    email = db.StringProperty(required=True)
    full_name = db.StringProperty()    
    birthday = db.DateProperty()
    avatar = db.BlobProperty()

如果我删除

avatar = img

然后是上面一行的错误。

4

2 回答 2

0

您错过的是文档中的以下内容:

Blob is for binary data, such as images. **It takes a str value**, but this value
is stored as a byte string and is not encoded as text. Use a Text instance for 
large text data.

您需要做的是通过以下教程上传 blob:https ://developers.google.com/appengine/docs/python/blobstore

在你的模型中:

 avatar = db.BlobProperty() <-- you store the key to the uploaded avatar.

因此,在您的模型中,您只需将密钥存储到 blob 引用而不是 blob 本身。我希望这很清楚。

还请查看以下教程,这对我有很大帮助:https ://gist.github.com/348025/d4fc873bda4a650210559f881738cc55a667ff2a

于 2013-06-08T11:59:20.340 回答
0

该异常来自_ReverseReferenceProperty班级。当您有db.ReferenceProperty指向它的模型时,这似乎被使用。您没有提供足够的详细信息,但我怀疑您有另一个使用 的模型db.ReferenceProperty,并且您设置collection_name为与 User 的现有属性之一相同的名称。

例如,如果您有这样的模型:

class Email(db.Model):
  user = db.ReferenceProperty(User, collection_name=email)

User.email 将变为只读,当您尝试设置它时会看到该异常。搜索您的其他型号,看看是否有一个带有db.ReferenceProperty(User, collection_name=...).

上的错误avatar = img)有点误导。这只是多行语句的最后一行。它可以是该声明的任何部分。

于 2013-06-10T03:08:15.487 回答