Skip to content. | Skip to navigation

Personal tools


You are here: Home / Tips / File Uploading and Handling

File Uploading and Handling

Image 和 File 檔案處理的相關功能,包括上傳、下載、線上顯示等。

除了用 Image 外,也可以使用 File 來上傳圖檔,主要差別在於 File 不會主動產生縮圖。利用 collective.pdfpeek 可以為上傳的 PDF 建立縮圖。

上傳 _ 開頭的檔名會產生錯誤 Fetch File (Image, PDF) from URL:

Image Attribute for EEA FacetedNavigation Thumbnail: Behavior + IObjectModifiedEvent possible example: eea.alchemy


read metadata form IPTC IIM properties if present collective.documentfile jQuery File Upload library

wildcard.foldercontents (Plone 4.3.4 pins) 支援批次上傳檔案的功能,在 Plone 5 則內建納入這個模組,名稱定為 plone.foldercontents,既有的類似模組也很多。

Archetypes 的 ATImage 和 ATFile 都繼承自 ATBlob,透過 ImageMixin 達到向後相容的效果。OFS 圖檔昇級轉換到 Dexterity 的討論,用 NamedBlobFiles 取代 OFSImage 的範例: collective.pdfpeek

使用 plone.api + NamedBlobFile

不同於一般方式,要在 form 裡建立一個 FileUpload 的物件欄位,想要取得物件路徑,可以使用 REQUEST.yourfile.filename 也就是 filename 屬性值來取得物件路徑。

NamedFile 不會把檔案存到 var/blobstorage 裡,NamedBlobFile 才會,除此之外,兩者功能相同。

參考 和 範例:

from plone.namedfile.file import NamedBlobImage
filename = u'myfile.png'

obj = createContentInContainer(folder, 'Image',
        image=NamedBlobImage(data=open(filename, 'r').read(), filename=filename))
<div tal:define="picture nocall:context/picture"
  <img tal:attribute="src string:${context/absolute_url}/@@download/picture/${picture/filename};
                      height picture/_height | nothing;
                      width picture/_width | nothing;" />


<div tal:define="images view/images"
   <span tal:repeat="obj images">
   <img src="" alt=""
    tal:attributes="src string:${obj/getURL}/image/preview" />

/portal_skins/archetypes/at_download: AttributeError: 'RequestContainer' object has no attribute 'getWrappedField' BlobWrapper vs File Instance: uwosh.pfg.d2c at_download stored as blobs make view override optional Generate cropped scales instead of uncropped scales after storage._cleanup() has run 版本議題造成 ImportError 錯誤 JPEG CMYK 模式在新版能處理得更好

view = self.img.restrictedTraverse('@@crop-image')
traverse = self.portal.REQUEST.traverseName
scales = traverse(self.img, '@@images')
uncropped_thumb = scales.scale('image', 'thumb')


Web Server 預設會有上傳的大小限制,以 Nginx 為例,在 /etc/nginx/proxy.conf 可找到 client_max_body_size    10m; 設定值。

Plone5 + HTTPs 造成檔案上傳 500Kb 限制 Dexterity Validator for Uploaded Files

# -*- coding: utf-8 -*-
from plone.namedfile.interfaces import INamedBlobImageField
# from import IImage
from zope.interface import Invalid
from z3c.form import validator

# 1 MB size limit
MAXSIZE = 1024 * 1024

class ImageFileSizeValidator(validator.FileUploadValidator):

    def validate(self, value):
        super(ImageFileSizeValidator, self).validate(value)

        if value.getSize() > MAXSIZE:
            raise Invalid("Image is too large (to many bytes)")

#                                        context=IImage,
<adapter factory=".validators.ImageFileSizeValidator" />

限制上傳的檔案類型 限制圖檔類型 上傳圖檔時限制 PDF 格式: Archetypes IObjectPostValidation Event Subscriber to Limit File Types

限制上傳圖檔的尺寸 IWebDAVObjectInitializedEvent FileSize Validator for Dexterity


File Image In Batch Via Zip: atreal.massloader

Image Contents Validation Methods among Archetypes Versions

Image Getter: collective.loremipsum

Using is_zipfile on ZPublisher.HTTPRequest.FileUpload

取消下載 Disable Download File

限制成員上傳的容量 限制上傳容量 Products.feedfeeder 範例 判斷上傳檔案是否存在

<span tal:condition="context/attachment/get_size">ATTACHMENT</span>

collective.quickupload list index out of range 相容性


Archetype File with restrictedtraverse

eea.pdf: 透過 PDF 下載內容 eea.converter 利用 urllib.urlretrieve(''+filename, filename) 可以批次下載圖檔

Products.ATContentTypes/lib/ getImageAsFile()

    image = self.getImageAsFile()
    image2 = StringIO()

    if image is not None:
        img =
        del image
        fmt = img.format
        img = img.transpose(method), fmt, quality=zconf.pil_config.quality)


File Data from Shell

obj = app.restrictedTraverse(„path/to/object)
data = str(obj,


Google Docs Microsoft Office Auto Rotate Dexterity Images Based on EXIF Information

Embedded PDF in File View

<object tal:condition="python:content_type.endswith('pdf')"
 class="viewembededfile" type="application/pdf"
 data="" tal:attributes="data location">
<a href="" tal:attributes="href location">
Click to Download
<embed src="" class="viewembededfile"
 type="application/pdf" tal:attributes="src location">

collective.documentviewer: PDF 和 Office 檔案都能線上顯示,進行文字辨識。LibreOffice 4.1 與 docsplit 版本問題Archetypes 與 Dexterity 參照問題

wc.pageturner: 搭配 Flex Paper 和 SWFtool 進行線上顯示。

collective.pdfjs: 搭配 Mozilla JavaScript PDF Reader 或 Native Reader Plugin 進行線上顯示。

Embedded PDF in File View: 搭配 HTTP Content Type 和 Native Reader Plugin 進行線上顯示。

z3c.rml: ReportLab's RML PDF generation XML format

IE 瀏覽器顯示 Flash z3c.form with NamedImageFieldWidget

在 Portlet 顯示圖檔 在 Related Item 顯示圖檔

resolveuid images jQuery LightBox PrettyPhoto

MediaElement.js: collective.mediaelementjs

MP3 Cut

CSS Paged Media PDF 中文字型可能要搭配新版 freetype 才行

辨識 OCR H264: OSX Safari avconv params


上傳 Zip 檔案可以建立內容 collective.documentfusion: fusion of the variables and bookmarks of a file field, LibreOffice as a service

TinyMCE Batch Uploading PDF Image Caption: html-to-captioned

PNG 支援背景透明功能: z3c.rml transparent



Reflecto Upload Large Files

>>> fldr['2011']['09']['China-and-the-West.pdf'].file
<plone.namedfile.file.NamedBlobFile object at 0x7f81a3c45398>
>>> dir(fldr['2011']['09']['China-and-the-West.pdf'].file)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getstate__',
'__hash__', '__implemented__', '__init__', '__module__', '__new__', '__providedBy__', '__provides__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'_data', '_getData', '_p_activate', '_p_changed', '_p_deactivate',
'_p_delattr', '_p_estimated_size', '_p_getattr', '_p_invalidate',
'_p_jar', '_p_mtime', '_p_oid', '_p_serial', '_p_setattr', '_p_state',
'_setData', 'data', 'filename', 'getSize', 'open', 'openDetached', 'size']
>>> fldr['2011']['09']['China-and-the-West.pdf'].file.filename
>>> fldr['2011']['09']['China-and-the-West.pdf'].file.__dict__
{'_blob': <zodb.blob.blob object at 0x7f81a3c45488>,
 'contentType': 'application/pdf', 'filename': u'China-and-the-West.pdf', 'size': 223747}

Bad Images:

>>> from zope.annotation import IAnnotations
>>> from import PAI_STORAGE_KEY
>>> all_images = app.Plone.portal_catalog(portal_type='Image')
>>> bad_images = [x.getObject() for x in all_images if PAI_STORAGE_KEY in IAnnotations(x.getObject())]
>>> dont_care = [(IAnnotations(x).pop(PAI_STORAGE_KEY), x.setModificationDate()) for x in bad_images]
>>> import transaction
>>> transaction.commit()


imgs = {'folder1': ['img1.jpg', 'img2.png'], 'folder2': ['myimg.png']}
for i in imgs.keys():
    for j in imgs[i]:
        urllib.urlretrieve(''+i+'/'+j, j)