1

I have a Form that includes a FileField and a CharField. Both work as expected.

Neither field is required by itself, but one of them has to be given. So I want to add a validation that fails if both are empty.

in forms.py:

class MyForm(forms.Form):
    mytext = forms.CharField(
        label = "Enter text",
        required=False
        )
    myfile = forms.FileField(
        label = "Or upload file",
        required=False
        )

    def clean(self):
        super(MyForm, self).clean()

        mytext_value = self.cleaned_data.get("mytext")
        myfile_value = self.cleaned_data.get("myfile")  # this remains empty, even after selecting a file! :-(

        if not mytext_value and not myfile_value:
            self.add_error("mytext", "Either text or file must be given!")

        return self.cleaned_data

This validation fails even if a file has been uploaded! (It does not fail if the text field has been used.)

If I disable the validation, the form works fine within the app. In views.py, I can get the uploaded file from the request (myfile_value = request.FILES.get("myfile")) and work with it.

But how do I get the content of the file during the clean() call, where I do not have a request, yet?

self.files gives me an empty MultiValueDict, self.data doesn't contain the key myfile at all, and in self.cleaned_data, myfile is None.

How can I check during form validation whether a FileField has been filled?

CodingCat
  • 4,999
  • 10
  • 37
  • 59
  • Not sure if that's the reason (worked with Django long time ago)... Try to change "super" part to ```super(MyForm, self).clean()``` also pick up cleaned_data from ```self.cleaned_data``` – Alexander B. Mar 02 '22 at 15:42
  • Also I would ```return self.cleaned_data``` at the end. As for get access to FileField - you should be fine (https://stackoverflow.com/questions/10055029/django-forms-filefield-validation). – Alexander B. Mar 02 '22 at 15:53
  • @AlexanderB. I made the changes you suggested, but it still comes up empty. :( – CodingCat Mar 03 '22 at 09:18

1 Answers1

2

The problem was not the form, but the associated view:

Wrong forms.py:

if request.method == "POST":
    form = MyForm(request.POST)
    if form.is_valid():
        mytext = request.POST.get("mytext")
        myfile = request.FILES.get("myfile")   

I didn't pass request.FILES to the form, so no wonder the validation didn't find it. While below this point, I retrieved the file directly from the request and was fine.

Right forms.py:

if request.method == "POST":
    form = MyForm(request.POST, request.FILES)
    if form.is_valid():
        mytext = form.cleaned_data.get("mytext")
        myfile = form.cleaned_data.get("myfile")                   
CodingCat
  • 4,999
  • 10
  • 37
  • 59