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?
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")