Formencode file upload validation

225 views
Skip to first unread message

Jamie Wilkinson

unread,
Aug 13, 2006, 10:44:21 PM8/13/06
to pylons-discuss
Hey,

Does anyone have an example of using FormEncode's
FieldStorageUploadConverter or FileUploadKeepr ? There's no example in the
docstrings and I'm just having a hard time applying them in the same way as
any of the other validators.

Ian Bicking

unread,
Aug 15, 2006, 11:59:55 PM8/15/06
to pylons-...@googlegroups.com

I've used them from times (I guess I must have written at least one of
them). They might be from FunFormKit days, and I might have used them
only modestly since then. FileStorageUploadConverter just converts any
spurious FileStorage values you might have in your request into strings.
Which probably isn't what you want to do in nearly any situation.

FileUploadKeeper saves the file to disk, and then if the rest of the
submission fails and you have to resubmit the content it'll give you a
hidden field that can take the place of re-uploading the file. Anyway,
it's meant to be used in a situation where you have a complex form and
an image upload in that form.

--
Ian Bicking | ia...@colorstudy.com | http://blog.ianbicking.org

Jamie Wilkinson

unread,
Aug 29, 2006, 9:00:52 PM8/29/06
to pylons-...@googlegroups.com

Ok.

I've got a bug where I try to validate a form with a file upload, and on
formencode/validators.py line 1450 it throws an AttributeError; the
cgi.FieldStorage doesn't have an attribute 'get'.

This is unexpected, because the docstring for FileUploadKeeper is pretty
clear that it handles both text and cgi.FieldStorage uploads.

(Incidentally, if I pass in a string to the form from with my paste.fixture
test app, then it also blows up saying 'str object has no attribute get'.)

Should something other than the cgi.FieldStorage be passed in as the value
to be validated here?

I guess I'm calling it wrong, but I'm not sure how to do it right. The
schema at the moment looks like this:

class BaseSchema(schema.Schema):
allow_extra_fields = True
filter_extra_fields = True

def validate(self, input):
try:
result = self.to_python(input)
return result, {}
except Invalid, e:
return {}, e.unpack_errors()

class NewProposalSchema(BaseSchema):
attachment = FileUploadKeeper()

and is called like:

defaults = dict(request.POST)
if defaults:
results, errors = NewProposalSchema().validate(defaults)

(if you've seen Ben's crud module, you'll recognise the pattern)

Any hints or examples on using FileUploadKeeper in the wild would be greatly
appreciated.

Daniel Lyons

unread,
Sep 22, 2006, 12:02:22 PM9/22/06
to pylons-discuss
Jamie,

This one's biting me also. I fixed it for the mean time by making a
copy of FileUploadKeeper and changing these lines:

def _to_python(self, value, state):
upload = value.get(self.upload_key)
static = value.get(self.static_key, '').strip()

into this:

def _to_python(self, value, state):
upload = value
static = None

Of course, this nullifies the benefit of not having to re-upload the
file. But I think there is a mismatch here between FormEncode and
Pylons.

Here's hoping someone who understands FileUploadKeeper will take a
minute and fix it. :)

--
Daniel Lyons

Jamie Wilkinson

unread,
Sep 27, 2006, 9:34:53 PM9/27/06
to pylons-...@googlegroups.com
This one time, at band camp, Daniel Lyons wrote:
>This one's biting me also. I fixed it for the mean time by making a
>copy of FileUploadKeeper and changing these lines:

I forgot about this message :)

I made my own validator, to use instead of FileUploadKeeper:

class FileUploadValidator(validators.FancyValidator):
def _to_python(self, value, state):
if isinstance(value, cgi.FieldStorage):
filename = value.filename
content = value.value
elif isinstance(value, str):
filename = None
content = value
return dict(filename=filename,
content=content)

then in a Schema I have something like this:

class NewCFPSchema(BaseSchema):
attachment = FileUploadValidator()
...

and the attachment dictionary gets the filename and content set correctly.
Still not sure why FileUploadKeeper didn't work, but this one's working well
for me now.

Reply all
Reply to author
Forward
0 new messages