it turned out that I could not do it as shown above because of
form.accepts. This already performs the upload so now I'm doing it
more like you suggested which is even more straightforward.
form = SQLFORM.factory(
Field('invoice_logo', 'upload', label=T('as.invoice_logo'),
uploadfolder=os.path.join(request.folder,'uploads/')),
Field('invoice_logo_filename',
label=T('as.invoice_logo_filename')),
... many other fields ...
table_name='admin_setting')
if form.accepts(request.vars, formname='admin_setting_form',
dbio=False):
if request.vars.invoice_logo != None:
if type(request.vars.invoice_logo) != str:
request.vars.invoice_logo_filename =
request.vars.invoice_logo.filename
invoice_logo_newfilename =
form.vars['invoice_logo_newfilename']
else:
del request.vars.invoice_logo # do not clear current logo
filename
for setting in request.vars:
if not setting.startswith('_'):
old_file = None
if setting == 'invoice_logo':
old_file = db(
db.admin_setting.name ==
'invoice_logo').select(db.admin_setting.value).first().value
value = invoice_logo_newfilename
else:
value = request.vars[setting]
if old_file:
try:
os.remove(os.path.join(request.folder,
'uploads/', old_file))
except OSError:
pass
db(
db.admin_setting.name ==
setting).update(value=value)
one question about the download:
def download():
import os
filename = request.args(0)
original_filename = request.vars.filename
filename = os.path.join(request.folder, 'uploads/', filename)
ret = open(filename, 'rb')
response.headers['Content-Type'] = 'application/octet-stream'
response.headers['Content-Disposition'] = 'inline; filename="%s"'
% original_filename
return ret.read()
do I have to take care about directory traversals and other security
risks? What's the easiest way to do this?