6

If I do not select a file and just click 'submit', I get the following error:-

Invalid pstruct: {'upload': "b'' is not a FieldStorage instance"}

This is not the behavior I get on the deform demo site where leaving it empty results in the more reasonable 'Required' error message.

Using my own validator as below does not solve the issue:-

def validate_file(node, value, **kwargs):
    if not value:
        raise colander.Invalid(node, "Please select a file")

class Schema(colander.MappingSchema):
    excel_file = colander.SchemaNode(deform.FileData(),
            widget=deform.widget.FileUploadWidget(tmpstore),
            validator=validate_file)

I can see that the error is raised, but the output of e.render() where e is the ValidationFailure from form.validate does not match the error itself. The relevant deform source code is in 'widget.py' where the _FieldStorage class checks whether cstruct has a file attribute and raises it's own Invalid exception.

Here's the function which does the validation call (bog standard stuff really), which returns the rendered page.

def generate_upload_form(request):
    form = deform.Form(upload_schema, buttons=('submit',))
    if getattr(request, 'POST') and 'submit' in request.POST:
        try:
            value_dict = form.validate(request.POST.items())
        except deform.ValidationFailure as e:  # Invalid form
            form = e.render()
        else:  # Successfully validated, now do operation
            upload_form_operation(request, value_dict)
    if isinstance(form, deform.Form):
        form = form.render()
    return form

How do I show my own error message without monkey-patching the deform codebase?

Ng Oon-Ee
  • 1,193
  • 1
  • 10
  • 26

1 Answers1

1

Are you sure you are actually submitted the form data correctly? This error normally happens when deform attempts to deserialize the submitted value via duck typing.

One particular item that get's overlooked is to make sure your HTML form has the additional enctype define e.g.

 enctype="multipart/form-data"

Without this the form submits the filename as a string which will then fail

Mr-F
  • 871
  • 7
  • 12
  • This may well be it (not having access to the system right now) but I'm not defining the form in html, just using the html directly from form.render(). Would that make this a bug (assuming it's the actual issue)? – Ng Oon-Ee Mar 22 '17 at 01:15
  • Having now checked the system, the form enctype is indeed multipart/form-data, so this isn't the source of the problem. – Ng Oon-Ee Mar 22 '17 at 06:50
  • @NgOon-Ee I think I need to see a bit more code. Is it possible to see how you are actually validating and handling the raised exception please? – Mr-F Mar 22 '17 at 10:24
  • Added that. As far as I can tell this is standard practice, first I create a form from the schema, then I use that form to validate against request.POST.items(). I catch the ValidationFailure and render it. The `else` path is probably unimportant for this question, as my issue happens when there's a ValidationFailure (if I do select a file then the `else` path activates properly). – Ng Oon-Ee Mar 23 '17 at 02:08