使用 Flask-Admin 上传多张图片

mrz*_*gle 2 python flask flask-admin

我试图让文件管理员上传多个文件,但不知道如何做到这一点。

目前在下面的参考中,我一次只能上传一个文件。

https://github.com/flask-admin/flask-admin/blob/master/examples/file/app.py
(文件的新链接:https : //github.com/mrjoes/flask-admin/blob/主/示例/文件/app.py )

我尝试更新 html 模板,multiple=""但这并没有帮助上传多个文件。


进一步研究这个我认为这个 html 文件需要有 multiple=""

Python27\Lib\site-packages\flask_admin\templates\bootstrap3\adminC:\Python27\Lib\site-packages\flask_admin\templates\bootstrap3\admin\lib.html

尽管我不确定在何处/如何添加此标签而不实际覆盖源文件。

sta*_*mer 5

你应该定制ImageUploadInputImageUploadField如下。

import ast
from PIL import Image
from wtforms.widgets import html_params, HTMLString
from wtforms.utils import unset_value
from flask_admin.helpers import get_url
from flask_admin.form.upload import ImageUploadField
from flask_admin._compat import string_types, urljoin

class MultipleImageUploadInput(object):
    empty_template = "<input %(file)s multiple>"

    # display multiple images in edit view of flask-admin
    data_template = ("<div class='image-thumbnail'>"
                     "   %(images)s"
                     "</div>"
                     "<input %(file)s multiple>")

    def __call__(self, field, **kwargs):

        kwargs.setdefault("id", field.id)
        kwargs.setdefault("name", field.name)

        args = {
            "file": html_params(type="file", **kwargs),
        }

        if field.data and isinstance(field.data, string_types):

            attributes = self.get_attributes(field)

            args["images"] = "&emsp;".join(["<img src='{}' /><input type='checkbox' name='{}-delete'>Delete</input>"
                                            .format(src, filename) for src, filename in attributes])

            template = self.data_template

        else:
            template = self.empty_template

        return HTMLString(template % args)

    def get_attributes(self, field):

        for item in ast.literal_eval(field.data):

            filename = item

            if field.thumbnail_size:
                filename = field.thumbnail_size(filename)

            if field.url_relative_path:
                filename = urljoin(field.url_relative_path, filename)

            yield get_url(field.endpoint, filename=filename), item

class MultipleImageUploadField(ImageUploadField):

    widget = MultipleImageUploadInput()

    def process(self, formdata, data=unset_value):

        self.formdata = formdata  # get the formdata to delete images
        return super(MultipleImageUploadField, self).process(formdata, data)

    def process_formdata(self, valuelist):

        self.data = list()

        for value in valuelist:
            if self._is_uploaded_file(value):
                self.data.append(value)

    def populate_obj(self, obj, name):

        field = getattr(obj, name, None)

        if field:

            filenames = ast.literal_eval(field)

            for filename in filenames[:]:
                if filename + "-delete" in self.formdata:
                    self._delete_file(filename)
                    filenames.remove(filename)
        else:
            filenames = list()

        for data in self.data:
            if self._is_uploaded_file(data):

                self.image = Image.open(data)

                filename = self.generate_name(obj, data)
                filename = self._save_file(data, filename)

                data.filename = filename

                filenames.append(filename)

        setattr(obj, name, str(filenames))
Run Code Online (Sandbox Code Playgroud)

之后,您可以将它们用作flask-admin中的图像上传示例

class ModelHasMultipleImages(db.Model):

    id = db.Column(db.Integer(), primary_key=1)

    # len of str representation of filename lists may exceed the len of field

    image = db.Column(db.String(128))  

class ModelViewHasMultipleImages(ModelView):

    def _list_thumbnail(view, context, model, name):

        if not model.image:
            return ''

        def gen_img(filename):
            return '<img src="{}">'.format(url_for('static', 
                   filename="images/custom/" + form.thumbgen_filename(image)))

        return Markup("<br />".join([gen_img(image) for image in ast.literal_eval(model.image)]))

    column_formatters = {'image': _list_thumbnail}

    form_extra_fields = {'image': MultipleImageUploadField("Images",
                                  base_path="app/static/images/custom",
                                  url_relative_path="images/custom/",
                                  thumbnail_size=(400, 300, 1))}
Run Code Online (Sandbox Code Playgroud)

ModelHasMultipleImages存储文件名列表的 str 表示的图像文件。