Search code examples
djangodjango-viewsdjango-forms

Validate Django form field before sumbitting


Django form has file field and clean_file method.

class UploadFileForm(forms.Form):
    file = forms.FileField()

    def clean_file(self):
        ...

And there is a button called 'Apply'

I want to validate the file when I select it, and if the validating is successful, I will click the Apply button which will send a post request with this file.

But I don't understand how I can validate file before submitting it or I should use form into form.

Or it will be in two forms, but then how to throw a file between them


Solution

  • The strategy I've used is to just temporarily save the file so that it persists between requests. Assuming that the validation you mentioned is manual, like previewing the file contents before committing to the database via your "apply" button, then this approach involves two separate requests.

    The process looks something like:

    1. Make a view with a form that accepts a file upload.
    2. In the view's POST handling, save the file to filesystem or other storage layer (I was using S3 due to running multiple servers). You can do some sanity checks here with Django's built-in validation, like checking the file extension or peeking at the format.
    3. Redirect from the file upload POST request to a different view, such as one with a form that has your "Apply" button.
    4. In this view, open the file from whatever path/backend that was just used to store it.
    5. Read the file and puts the contents into a Python data structure. My use case mostly involved parsing CSV files.
    6. Use like any other Python variable in your views, contexts, and/or forms. Depending on the data, you may be able to populate a form from the data read from the file contents using the initial attribute/parameter of Django's Form objects.
    7. Clean up (or archive to a long-term storage layer) the uploaded file when you're done.

    If your validation process is automated, the stateless nature of HTTP requests/responses is still the key concept. If you don't persist the file outside of memory, the file is essentially gone once the validation fires back the HTTP response to the browser.