Django: проверка поля файла в модели с использованием python-magic

У меня есть модель, содержащая поле файла. Я хочу ограничить его файлами PDF. Я написал чистый метод в модели, потому что я хочу также проверить создание модели на уровне администратора и оболочки. Но он не работает в методе чистой модели. Однако метод чистой формы работает.

class mymodel(models.Model):
    myfile = models.FileField()

    def clean():
        mime = magic.from_buffer(self.myfile.read(), mime=True)
        print mime
        if not mime == 'application/pdf':
            raise ValidationError('File must be a PDF document')

class myform(forms.ModelForm):
    class Meta:
        model = mymodel
        fields = '__all__'

    def clean_myfile(self):
        file = self.cleaned_data.get('myfile')
        mime = magic.from_buffer(file.read(), mime=True)
        print mime
        if not mime == 'application/pdf':
            raise forms.ValidationError('File must be a PDF document')
        else:
            return file

Если я загружаю pdf, mime в методе очистки формы правильно проверяет (печатает «приложение / pdf»). Но метод чистой модели не проходит проверку. Он печатает mime как «application/x-пусто». Где я делаю неправильно?

Также еще одна проблема заключается в том, что если метод очистки модели вызывает ошибку проверки, она не отображается как ошибка поля в форме, а отображается как ошибки, не связанные с полем. Почему так ?


person Chaitanya Patel    schedule 01.10.2016    source источник


Ответы (2)


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

Вы уже делаете правильную вещь в форме

def clean_file(self):
        yourfile = self.cleaned_data.get("your_filename_on_template", False)
        filetype = magic.from_buffer(yourfile.read())
        if not "application/pdf" in filetype:
            raise ValidationError("File is not PDF.")
        return yourfile

Если вы хотите использовать чистую модель, вы можете создать свой собственный валидатор.

https://stackoverflow.com/a/27916582/5518973

Вы используете проверку python-django на стороне сервера, но javascript также является хорошим способом проверки клиентской части файла. Для проверки регулярного выражения javascript вы можете найти этот ответ

https://stackoverflow.com/a/17067242/5518973

или если вы можете использовать плагины, вы можете использовать плагин проверки jquery

https://jqueryvalidation.org/

person Aniket Pawar    schedule 01.10.2016
comment
К сожалению, приведенный выше код не будет работать. filetype будет что-то вроде 'PDF document, version 1.3'. Вам понадобится задание filetype = magic.from_buffer(yourfile.read(), mime=True), чтобы получить "application/pdf" - person Rob L; 20.06.2017

fields = '__all__'

Предложение от Two Scoops of Django: Best Practices for Django 1.8

26.14 Не используйте ModelForms.Meta.fields = "__ all __" — сюда входят все поля модели в вашей форме модели. Это короткий путь, и опасный. Это очень похоже на то, что мы описываем в разделе 26.13 (Не используйте ModelForms.Meta.exclude), и даже с пользовательским кодом проверки подвергает проекты уязвимостям массового назначения на основе форм. Мы выступаем за то, чтобы максимально избегать этой техники, так как считаем, что просто невозможно уловить все варианты ввода.

person Michel Rodrigues    schedule 16.11.2016