Моя цель - ограничить FileField в Django ModelForm для PDF файлов и документов Word. Ответы, с которыми я столкнулся, касаются создания отдельного обработчика файлов, но я не уверен, как это сделать в контексте ModelForm. Есть ли параметр в settings.py, который я могу использовать для ограничения типов файлов загрузки?
Как ограничить типы файлов при загрузке файлов для ModelForms с помощью FileFields?
Ответ 1
Я обрабатываю это, используя метод clean_ [your_field] в ModelForm. Вы можете установить список допустимых расширений файлов в settings.py для проверки в своем чистом методе, но нет ничего встроенного в settings.py для ограничения типов загрузки.
Django-Filebrowser, например, использует подход к созданию списка допустимых расширений файлов в settings.py.
Надеюсь, что это поможет тебе.
Ответ 2
Создайте метод проверки, например:
def validate_file_extension(value):
if not value.name.endswith('.pdf'):
raise ValidationError(u'Error message')
и включите его в валидаторы FileField, например:
actual_file = models.FileField(upload_to='uploaded_files', validators=[validate_file_extension])
Кроме того, вместо того, чтобы вручную устанавливать расширения, которые позволяет ваша модель, вы должны создать список на свой файл settings.py и перебрать его.
Изменить
Чтобы фильтровать несколько файлов:
def validate_file_extension(value):
import os
ext = os.path.splitext(value.name)[1]
valid_extensions = ['.pdf','.doc','.docx']
if not ext in valid_extensions:
raise ValidationError(u'File not supported!')
Ответ 3
Проверка с расширением имени файла не является последовательным способом. Например, я могу переименовать picture.jpg в picture.pdf, и проверка не приведет к ошибке.
Лучший подход - проверить содержимое content_type файла.
Метод проверки
def validate_file_extension(value):
if value.file.content_type != 'application/pdf':
raise ValidationError(u'Error message')
Использование
actual_file = models.FileField(upload_to='uploaded_files', validators=[validate_file_extension])
Ответ 4
Для более общего использования я написал небольшой класс ExtensionValidator
, который расширяет встроенный Django RegexValidator
. Он принимает одно или несколько расширений, а также необязательное настраиваемое сообщение об ошибке.
class ExtensionValidator(RegexValidator):
def __init__(self, extensions, message=None):
if not hasattr(extensions, '__iter__'):
extensions = [extensions]
regex = '\.(%s)$' % '|'.join(extensions)
if message is None:
message = 'File type not supported. Accepted types are: %s.' % ', '.join(extensions)
super(ExtensionValidator, self).__init__(regex, message)
def __call__(self, value):
super(ExtensionValidator, self).__call__(value.name)
Теперь вы можете определить встроенный валидатор с полем, например:
my_file = models.FileField('My file', validators=[ExtensionValidator(['pdf', 'doc', 'docx'])])
Ответ 5
Более простой способ сделать это, как показано ниже в вашей форме
file = forms.FileField(widget=forms.FileInput(attrs={'accept':'application/pdf'}))
Ответ 6
Я использую что-то в этих строках (обратите внимание: для этого требуется "pip install filemagic" ):
import magic
def validate_mime_type(value):
supported_types=['application/pdf',]
with magic.Magic(flags=magic.MAGIC_MIME_TYPE) as m:
mime_type=m.id_buffer(value.file.read(1024))
value.file.seek(0)
if mime_type not in supported_types:
raise ValidationError(u'Unsupported file type.')
Возможно, вы также можете включить в него предыдущие примеры - например, также проверьте тип добавочного/загруженного (который может быть быстрее, чем первичная проверка, чем магия). Это все еще не является надежным - но это лучше, поскольку оно полагается больше о данных в файле, а не о браузерах.
Примечание. Это функция валидатора, которую вы хотите добавить в список валидаторов для модели FileField.