如果您只是重命名文件,這將打破下載機制。此外,有時您可能想用不同於原始文件的名稱保存文件。讓我們假設你有以下型號:
db.define_table("files",
Field("name", unique=True),
Field("file", "upload"))
你需要上傳現場定製店擴展和檢索功能:
Field("file", "upload", custom_store=store_file, custom_retrieve=retrieve_file)
的功能是簡單地寫/從一個固定的上傳目錄中讀取文件:
import os
import shutil
def store_file(file, filename=None, path=None):
path = "applications/app_name/uploads"
if not os.path.exists(path):
os.makedirs(path)
pathfilename = os.path.join(path, filename)
dest_file = open(pathfilename, 'wb')
try:
shutil.copyfileobj(file, dest_file)
finally:
dest_file.close()
return filename
def retrieve_file(filename, path=None):
path = "applications/app_name/uploads"
return (filename, open(os.path.join(path, filename), 'rb'))
現在控制器你需要的數據庫插入/更新完成之前修改form.vars並設置文件名。如果您想保留上傳文件的原始名稱,則不需要。
def validate(form):
# set the uploaded file name equal to a name given in the form
if form.vars.file is not None:
form.vars.file.filename = form.vars.name
您還需要定義一個函數來下載文件,如response.download構建將無法正常工作:
import contenttype as c
def download():
if not request.args:
raise HTTP(404)
name = request.args[-1]
field = db["files"]["file"]
try:
(filename, file) = field.retrieve(name)
except IOError:
raise HTTP(404)
response.headers["Content-Type"] = c.contenttype(name)
response.headers["Content-Disposition"] = "attachment; filename=%s" % name
stream = response.stream(file, chunk_size=64*1024, request=request)
raise HTTP(200, stream, **response.headers)
要連接的點,你需要建立形式。在下面的示例中,我使用的是比舊式表單更好的新網格機制(但尚未記錄在書中)。
upload = lambda filename: URL("download", args=[filename])
def index():
grid = SQLFORM.grid(db.files, onvalidation=validate, upload=upload)
return {"grid":grid}
如果你不希望網格的所有花式,等效控制器代碼:
def index():
if len(request.args):
form=SQLFORM(db.files, request.args[0], upload=URL("download"))
else:
form=SQLFORM(db.files, upload=URL("download"))
if form.process(onvalidation=validate).accepted:
response.flash = "files updated"
return {"form":form}
與request.vars.name_of_file.filename我得到的原始文件名,但如何重命名上傳。我應該使用os.rename嗎? 我上傳不同的zip文件,所以他們需要name_of_file.zip謝謝 – Yebach
您也可以跳過'form.accepts'並處理自己保存的文件。但是,不要使用用戶上傳的文件來完成此操作,因爲您將對目錄遍歷攻擊開放。 – Anthony
如何設置web2py沒有文件編碼。事情是我想上傳的文件存儲在一個文件夾中的原始文件名,因爲我有另一個腳本然後處理它,文件名是重要的文件處理? – Yebach