Search code examples
djangodjango-formsdjango-testing

Testing a Django Form with a CSV upload


I have a form that the user upload's a CSV into for data processing. I'm currently trying to test the form.is_valid() method. However I am following the Django documentation, and the form is still returning an error that the field requires a value. Any ideas?

The Documentation

The documentation show the following example -

>>> c = Client()
>>> with open('wishlist.doc') as fp:
...     c.post('/customers/wishes/', {'name': 'fred', 'attachment': fp})

The Test

class TestImportCSVForm(TestCase):

    def test_form_valid(self):
        with open('fake.csv', 'r', newline='') as csvfile:
            form_data = {
                'csv_file':  csvfile,
            }
            form = ImportCSVForm(data=form_data)
            self.assertTrue(form.is_valid())

The Form

class ImportCSVForm(forms.Form):
    """ Form for uploading CSVs """
    csv_file = forms.FileField(
        label=_("CSV File"),
        help_text=_("Upload a CSV"))

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
            'csv_file',
            HTML("""<hr>"""),
            ButtonHolder(
                Submit('submit', 'Submit', css_class='btn btn-primary')
            )
        )

The error when I run the test

(Pdb) form.errors
{'csv_file': ['This field is required.']}

Solution

  • You need to pass files in to a form with the files kwarg.

    class TestImportCSVForm(TestCase):

    def test_form_valid(self):
        with File(file=tempfile.NamedTemporaryFile()) as csvfile:
            csvfile.write(b'test')
            csvfile.flush()
            form_data = {
                'csv_file':  csvfile,
            }
            form = ImportCSVForm(files=form_data)
            self.assertTrue(form.is_valid())