Объект Flask Wtforms FileField не имеет прочитанного атрибута

Я пытаюсь загрузить изображения в корзину Amazon S3 из приложения Flask. Вот мой код:

def s3upload(image, acl='public-read'):
    key = app.config['S3_KEY']
    secret = app.config['S3_SECRET']
    bucket = app.config['S3_BUCKET']

    conn = S3Connection(key, secret)
    mybucket = conn.get_bucket(bucket)

    r = redis.StrictRedis(connection_pool = pool)
    iid = r.incr('image')
    now = time.time()
    r.zadd('image:created_on', now, iid)


    k = Key(mybucket)
    k.key = iid
    k.set_contents_from_string(image.read())

    return iid

@app.route('/', methods = ['GET', 'POST'])
def index():
    form = ImageForm(request.form)
    print 'CHECKING REQUEST'
    if request.method == 'POST' and form.image:
        print 'VALID REQUEST'
        image = form.image.read()
        upload = s3upload(image)
        print upload
    else:
        image = None

    r = redis.StrictRedis(connection_pool = pool)
    last_ten = r.zrange('image:created_on', 0, 9)
    print last_ten
    images = []

    key = app.config['S3_KEY']
    secret = app.config['S3_SECRET']
    bucket = app.config['S3_BUCKET']

    conn = S3Connection(key, secret)
    mybucket = conn.get_bucket(bucket)  


    for image in last_ten:

        images.append(mybucket.get_key(image, validate = False))


    return render_template('index.html', form=form, images=images, image=image)

Однако я получаю сообщение об ошибке k.set_contents_from_string(image.read()), говорящее 'FileField' object has no attribute 'read'. Все, что я подготовил, указывало на то, что это правильный способ загрузки изображения на S3, и я нашел несколько примеров, когда они вызывают .read() для объекта FileField, и это работает нормально. Спасибо за вашу помощь.


person apardes    schedule 12.03.2014    source источник
comment
Вы используете form.image.data.read(). В идеале вы должны передавать содержимое файла в потоковом режиме, а не считывать его в память.   -  person Blender    schedule 12.03.2014
comment
Можете ли вы опубликовать пример того, как это будет работать, пожалуйста?   -  person apardes    schedule 12.03.2014
comment
Была такая же проблема. Заметил опечатку в атрибуте enctype="multipart/form-data" формы.   -  person Andrey Borisko    schedule 30.11.2016


Ответы (2)


FileField объекты имеют атрибут data:

k.set_contents_from_string(image.data.read())
person Blender    schedule 12.03.2014
comment
Возвращает ту же ошибку 'FileField' object has no attribute 'stream' - person apardes; 12.03.2014
comment
@ haye321: Вы импортируете FileField из flask_wtf или из wtforms? Вы, вероятно, импортируете его из wtforms, что также может быть причиной вашей первоначальной проблемы. - person Blender; 12.03.2014
comment
Я импортирую его из flask_wtf. - person apardes; 12.03.2014
comment
@ haye321: Какую версию Flask-WTF вы используете? - person Blender; 12.03.2014
comment
Я использую версию 9.4, она была загружена с pypi сегодня утром. - person apardes; 12.03.2014
comment
@ haye321: Упс, я совсем забыл часть .data. Теперь это должно работать. - person Blender; 12.03.2014
comment
давайте продолжим это обсуждение в чате - person apardes; 12.03.2014
comment
@ haye321: Вы все еще звоните image = form.image.read(). Вам нужно всего upload = s3upload(form.image). - person Blender; 12.03.2014
comment
Я удалил .read() и использовал исключительно .stream. Когда я удаляю оба и просто отправляю s3upload(form.image) с set_content_from_stream, он возвращает BotoClientError: s3 does not support chunked transfer - person apardes; 12.03.2014
comment
@ haye321: Это странно. Я думаю, вам придется делать то, что вы делали изначально: k.set_contents_from_string(image.data.read()) - person Blender; 12.03.2014
comment
Это возвращает нас к исходной проблеме. Использование этого возвращает 'unicode' object has no attribute 'read' - person apardes; 12.03.2014

Как насчет

import os

filestream = form.image.raw_data[0]
filestream.seek(0, os.SEEK_END)
read_data = filestream.tell()

or

read_data = form.image.raw_data[0].read()
person iChux    schedule 05.06.2015