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