Flask-Uploads允许您的应用程序灵活有效地处理文件上传和服务上传的文件。您可以创建不同的上传集—一组用于文档附件,一组用于照片,等等。应用程序可以配置为将它们保存在不同的位置,并为它们生成不同的url。

配置

如果您只是部署一个使用Flask-Uploads的应用程序,那么您可以从应用程序的配置中广泛地定制它的行为。检查应用程序的文档或源代码,查看它如何加载配置。

下面的设置适用于一组上传,用集合(i.e. PHOTOS, ATTACHMENTS) 的名称替换 FILES 

函数说明
UPLOADED_FILES_DEST 这表示上载文件将保存到的目录。
UPLOADED_FILES_URL 如果您设置了一个服务器来服务于这个集合中的文件,那么这应该是它们可以公开访问的URL。包括后面的斜杠。
UPLOADED_FILES_ALLOW 这允许您允许代码中的上载集不允许的文件扩展名。
UPLOADED_FILES_DENY 这允许您拒绝代码中上载集所允许的文件扩展名。

但是,为了节省配置时间,如果不提供适当的设置,可以提供两种设置作为“默认值”应用。

  • UPLOADS_DEFAULT_DEST
    • 如果您设置了这个,那么如果上传集的目标没有以其他方式声明,那么它的上传将存储在这个目录的子目录中。比如,你设置它为 /var/uploads,然后一个名为photos的集合将把它的上传存储在 /var/uploads/photos
  • UPLOADS_DEFAULT_URL
    • 如果将服务器设置为UPLOADS_DEFAULT_DEST提供服务,然后在这里设置服务器的基本URL。继续上面的例子,如果 /var/uploads 可以从http://localhost:5001访问,则将其设置为http://localhost:5001/,并且照片集的url将以http://localhost:5001/photos开始,包括后面的斜杠。

但是,您不需要设置任何_URL设置—如果不设置,那么Flask将在内部提供这些设置。他们只是在那里,所以如果你有大量的的上传流量,你可以有一个更快的生产服务器,如Nginx或Lighttpd服务上传。

上传集

“上传集”是文件的单一集合。你只需要在代码中声明:

photos = UploadSet('photos', IMAGES)

然后,您可以使用save方法保存上传的文件以及访问它们的pathurl。例如:

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST' and 'photo' in request.files:
        filename = photos.save(request.files['photo'])
        rec = Photo(filename=filename, user=g.user.id)
        rec.store()
        flash("Photo saved.")
        return redirect(url_for('show', id=rec.id))
    return render_template('upload.html')

@app.route('/photo/<id>')
def show(id):
    photo = Photo.load(id)
    if photo is None:
        abort(404)
    url = photos.url(photo.filename)
    return render_template('show.html', url=url, photo=photo)

如果你有一个“默认位置”存储上传-例如,如果你的应用程序有一个像 Zine 一样的“实例”目录,并且uploads应该保存到实例目录的uploads文件夹中——你可以将一个default_dest可调用函数传递给set构造函数。它将应用程序作为它的参数。例如:

media = UploadSet('media', default_dest=lambda app: app.instance_root)

不过,这并不会阻止在配置中设置不同的目标。这只是为您的用户节省一点配置时间。

应用程序配置

上传集的配置存储在一个应用程序中。这样,你可以让多个应用程序同时使用上传集。使用configure_uploads函数加载上载集的配置。你传入应用程序和所有你想配置的上传集。多次调用configure_uploads是安全的。

configure_uploads(app, (photos, media))

如果你的应用程序有一个工厂函数,这是放置这个调用的好地方。

此外,您还可以使用patch_request_class来修补应用程序的request_class,使其具有上传的最大大小。默认情况下,没有限制,所以脚本小子有可能通过上传巨大的文件来崩溃您的服务器。调用它将安装一个限制,防止它加载超过一定数量的数据。

patch_request_class(app)        # 16 百万字节
patch_request_class(app, 32 * 1024 * 1024)
                                # 32 百万字节

如果您需要上传大型文件,您可能需要研究另一个解决方案,比如rsync。

文件上传表单

要真正上载文件,您需要正确地设置表单。上传文件的表单需要将其方法设置为POST,将其enctype设置为multipart/form-data。如果将它设置为GET,它将完全不能工作,如果不设置enctype,则只传输文件名。

字段本身应该是<input type=file>

<form method=POST enctype=multipart/form-data action="{{ url_for('upload') }}">
    ...
    <input type=file name=photo>
    ...
</form>

API

这里是API文档。它们直接从源代码生成。

Upload Sets

class flaskext.uploads.UploadSet(name=’files’extensions=(‘txt’‘rtf’‘odf’‘ods’‘gnumeric’‘abw’‘doc’‘docx’‘xls’‘xlsx’‘jpg’‘jpe’‘jpeg’‘png’‘gif’‘svg’‘bmp’‘csv’‘ini’‘json’‘plist’‘xml’‘yaml’‘yml’)default_dest=None)

这表示一组上载的文件。每个上传集独立于其他上传集。这可以跨多个应用程序实例重用,因为所有配置都存储在应用程序对象本身上,并且可以使用flask.current_app.

  • 参数
    • name
      • 此上载集的名称。它默认为文件,但您可以选择任何您想要的字母数字名称。(为了简单起见,最好使用复数名词。)
    • extensions
      • 最简单的方法是将扩展预置(例如,TEXT + DOCUMENTS + IMAGES )添加到一起。它可以被UPLOADED_X_ALLOWUPLOADED_X_DENY配置参数覆盖。默认值是DEFAULTS
    • default_dest
      • 如果给定,这应该是一个可调用的。如果您用应用程序调用它,它应该返回该应用程序的默认上载目标路径
  • 函数
    • config
      • 这将获得当前配置。默认情况下,它会查找当前应用程序并从中获取配置。但是,如果您不想全身心地设置应用程序,或者它在请求上下文之外,那么可以将_config属性设置为UploadConfiguration实例,然后在完成之后将其设置为None
    • extension_allowed(ext)
      • 这决定是否允许特定的扩展。它是由file_allowed调用的,所以如果您覆盖了它,但仍然想检查扩展名,请回调到这个。
      • 参数:ext
        要检查的扩展名。
    • file_allowed(storagebasename)
      • 这表示是否允许文件。如果给定的是
        werkzeug.FileStorage ,则返回True。对象可以用给定的basename保存,如果不能,则为False。默认实现只检查扩展名,所以如果需要,可以覆盖它。
      • 参数:
      • storage – 需要核实的werkzeug.FileStorage
      • basename – 它将保存在basename 下面。
    • resolve_conflict(target_folderbasename)
      • 如果目标文件夹中已经存在具有选定名称的文件,则调用此方法来解决冲突。它应该为文件返回一个新的basename。
      • 默认实现将名称和扩展分隔开,并将后缀添加到由下划线和数字组成的名称中,并进行尝试,直到找到一个不存在的后缀。
      • 参数:
      • target_folder – 指向目标的绝对路径。
      • basename -文件的原始basename。
    • save(storagefolder=Nonename=None)
      • 这样就在这个上传集节约了一个 werkzeug.FileStorage。文件存储到此上传集。如果不允许上传,将会引发一个 UploadNotAllowed  错误。否则,将保存文件并返回其名称(包括文件夹)。
      • 参数
      • storage –  要保存的上载文件
      • folder –  要保存到的上载集中的子文件夹。
      • name – 将文件保存为。如果以点结束,文件的扩展名将被附加到末尾。
    • url(filename)
      • 此函数获取上载到此集合的文件的URL。它不检查该文件是否存在。
      • 参数:
      • filename – 返回URL的文件名。  

class flaskext.uploads.UploadConfiguration(destinationbase_url=Noneallow=()deny=())

这保存了单个UploadSet的配置。构造函数的参数也是属性。

  • destination – 要将文件保存到的目录。
  • base_url – 文件可以从URL(以/结尾)下载。如果是None,Flask-Uploads将为文件本身提供服务。
  • allow – 允许的扩展列表,即使它们不在UploadSet扩展列表中。
  • deny – 要拒绝的扩展列表,即使它们位于UploadSet扩展列表中。

应用程序设置

flaskext.uploads.configure_uploads(appupload_sets)

在应用程序配置好之后调用它。它会遍历所有的上传集,获取它们的配置,并将配置存储在app上。如果没有设置upload模块,它还会注册uploads模块。

  • 参数
  • app 
    • 获取配置的Flask实例
  • upload_sets 

flaskext.uploads.patch_request_class(appsize=16777216)

默认情况下,Flask将接受上传到任意大小。不幸的是,这可能会导致一个安全漏洞:有人上传了一个巨大的文件,当它耗尽内存时,服务器就会崩溃。在应用程序上调用这个函数将修补应用程序的请求类,以便当它达到一定的大小时,它将自动引发HTTP错误。

  • 参数
  • app 
    • 应用程序补丁的请求类。
  • size 
    • 要接受的最大大小,以字节为单位。默认值是16mib。

发表回复