我有这个型号:
class Product(ndb.Model):
title = ndb.StringProperty()
description = ndb.TextProperty()
img = ndb.BlobKeyProperty(indexed=False)
我需要一个html表单来读取字段的值(标题和描述)并读取图像(从文件字段中),并保留值NDB对象,Blobstore中的图像并更新字段BlobKeyProperty正确。
当我使用wtforms时,我尝试使用如下形式执行此操作:
class ProductForm(Form):
title = fields.TextField('Title', [validators.Required(), validators.Length(min=4, max=25)])
description = fields.TextAreaField('Description')
img = fields.FileField('img')
表单正确显示文件字段,但在POST中,它不起作用,因为我不知道如何读取文件,将文件保存到Blobstore并更新BlobKeyProperty。
我的处理程序是这样的:
class ProductHandler(BaseHandler):
def new(self):
if self.request.POST:
data = ProductForm(self.request.POST)
if data.validate():
model = Product()
data.populate_obj(model)
model.put()
self.add_message("Product add!", 'success')
return self.redirect_to("product-list")
else:
self.add_message("Product not add!", 'error')
params = {
'form': ProductForm(),
"kind": "product",
}
return self.render_template('admin/new.html', **params)
错误是预期的str,得到了u'image.jpg'
如果有人可以帮助我,我会很感激!
答案 0 :(得分:0)
我找到的唯一解决方案是使用https://developers.google.com/appengine/docs/python/blobstore/#Python_Writing_files_to_the_Blobstore
中描述的已弃用的低级API我为FileField创建了一个wtform验证器。
我改变了:
img = fields.FileField('img')
要:
img = fields.FileField('img', [create_upload_file])
我写了这个验证器:
def create_upload_file(form, field):
file_name = files.blobstore.create(mime_type=field.data.type, _blobinfo_uploaded_filename=field.data.filename)
with files.open(file_name, 'a') as f:
f.write(field.data.file.read())
files.finalize(file_name)
blob_key = files.blobstore.get_blob_key(file_name)
field.data = blob_key
验证器在blobstore中创建blob,然后将字段数据从FieldStorage更改为blob_key。
我认为这不是最好的解决方案,但它现在有效。