ファイルの名前を変更するだけで、ダウンロードメカニズムが破られます。さらに、元のファイルとは異なる名前でファイルを保存することもあります。あなたは次のモデルを持っていると仮定しましょう:
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を変更し、ファイル名を設定する必要があります。アップロードしたファイルの元の名前を保持したい場合は、これは必要ありません。あなたはまた、response.downloadでビルドが動作しませんよう、ファイルをダウンロードする機能を定義する必要が
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
:
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でファイルエンコーディングを設定しない方法。問題は、アップロードしたファイルを元のファイル名で1つのフォルダに保存したいからです。ファイルを処理するために別のスクリプトがあり、ファイル名がファイル処理にとって重要ですか? – Yebach