So how does it work for other form elements? I'm guessing they are stored in session. So the way to go would be to store the uploaded file in session too and then on form resubmission check what to display. If file is in session the input field should look as on update of an existing object (i.e. having a link to a file next to it).
So having a controller as below, we would need to store file on error but also read it to form.vars on validation: def validate(form): # read file from session if form.vars.file is None and session.file: form.vars.file = session.file def test(): form = SQLFORM.factory( Field('file', 'upload'), Field('name', requires=IS_NOT_EMPTY())) if form.process(onvalidation=validate).accepted: response.flash = 'OK' # delete session object session.forget(response) elif form.errors: response.flash = 'errors' # store file in session session.file = form.vars.file return dict(form=form) Unfortunately this doesn't work as file objects cannot be pickled. Any other ideas? Maybe mocking the CGI file with StringIO?