Я создал пользовательский ImageUploadField в Flask-Admin для загрузки изображений в S3. Он отлично работает, за исключением случаев, когда я выбираю одну запись - тег img src теперь добавляется /static/ ко всем моим файловым маршрутам, и я не вижу изображение. Это сгенерированный тег от Flask-Admin:

<div class="image-thumbnail"> <img src="/static/https://mybucket.s3.amazonaws.com/mypicture.jpg"> </div><input class="form-control" id="image1" name="image1" type="file"></div>

Я также обслуживаю статические файлы из своего приложения, поэтому глобальное изменение каталога static не будет хорошей идеей.

Похоже, в ImageUploadField есть несколько свойств, которые можно изменить для этой цели (endpoint, url_relative_path, relative_path и base_path), но я все еще не смог почини это.

1
Anconia 8 Дек 2016 в 17:00

3 ответа

Лучший ответ

Оказывается, widget отвечал за генерацию URL. Он также ищет изображение в конечной точке static (следовательно, по умолчанию endpoint по умолчанию static при инициализации класса ImageUploadField). Чтобы решить эту проблему, я создал подкласс этого виджета и изменил HTML-код так, чтобы он указывал непосредственно на URL-адрес S3, который хранится в форме.

Хотя о документах Flask-Admin подробно не говорится о виджетах, вы можете увидеть, как они работают из фрагментов исходный код.

Ниже приведен полный код виджета и часть моего пользовательского ImageUploadField.

class S3ImageUploadInput(ImageUploadInput):

    def __call__(self, field, **kwargs):
        kwargs.setdefault('id', field.id)
        kwargs.setdefault('name', field.name)

        args = {
            'file': html_params(type='file',
                                **kwargs),
            'marker': '_%s-delete' % field.name
        }

        if field.data and isinstance(field.data, string_types):
            # calling field.data to directly return S3 URL
            url = field.data
            args['image'] = html_params(src=url)

            template = self.data_template
        else:
            template = self.empty_template

        return HTMLString(template % args)


class S3ImageUploadField(ImageUploadField):

    widget = S3ImageUploadInput()

    def __init__(self, *args, **kwargs):
        super(S3ImageUploadField, self).__init__(*args, **kwargs)
0
Anconia 9 Дек 2016 в 14:02

Flask-Admin использует urlparse.urljoin для создания имени файла, поэтому может предшествовать '/static', если у параметра 'relative_path' нет косой черты.

Просто мысль, удачи!

0
Deckey 8 Дек 2016 в 14:55

Добавить "конечную точку", чтобы продиктовать some_image

form_args = dict(
    some_image=dict(
        endpoint=you_url_complete,
        base_path='/some/folder/static',
        relative_path='some_image/',
        url_relative_path='uploads/',
        namegen=your_namegen_func_here,
        storage_type_field='some_image_storage_type',
        bucket_name_field='some_image_storage_bucket_name',
    )
)
0
Victor Narcizo 8 Фев 2017 в 23:08