Django проверяет FileField с помощью функции clean()

У меня есть форма, которая включает поле FileField и поле CharField. Оба работают как ожидалось.

Ни одно из полей не является обязательным само по себе, но одно из них должно быть указано. Поэтому я хочу добавить проверку, которая завершится неудачей, если оба поля будут пусты.

в 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):
        cleaned_data = super().clean()

        mytext_value = cleaned_data.get("mytext")
        myfile_value = 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!")

Эта проверка не работает, даже если был загружен файл! (Она не проходит, если использовалось текстовое поле)

Если я отключаю валидацию, форма работает нормально в приложении. В views.py я могу получить загруженный файл из запроса (myfile_value = request.FILES.get("myfile")) и работать с ним.

Но как мне получить содержимое файла во время вызова clean(), когда у меня еще нет запроса?

self.files дает мне пустой MultiValueDict, self.data вообще не содержит ключа myfile, а в cleaned_data, myfile является None.

Как проверить при валидации формы, было ли заполнено поле FileField?

Проблема была не в форме, а в связанном с ней представлении:

Неправильные формы.py:

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

Я не передавал request.FILES в форму, поэтому неудивительно, что валидация не нашла его. Хотя ниже этого пункта я извлек файл непосредственно из запроса и все было в порядке.

Правильные формы.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")                   
Вернуться на верх