Django:使用 python-magic 在模型中验证文件字段

Django: file field validation in model using python-magic

我有一个包含文件字段的模型。我想将其限制为 pdf 文件。我在模型中编写了干净的方法,因为我还想检查管理员和 shell 级别的模型创建。但它不适用于模型清理方法。但是 form clean 方法有效。

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 会正确验证(打印 'application/pdf')。但是模型清理方法没有验证。它将 mime 打印为 'application/x-empty'。我哪里做错了?

还有一个问题是,如果模型清理方法引发验证错误,它不会在表单中显示为字段错误,而是显示为非字段错误。为什么会这样?

由于您使用的是表单验证,因此您不必担心模型清理方法

你已经在做正确的事情

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

如果你想使用 model clean,你可以制作自己的验证器

您正在使用服务器端 python-django 验证,但 javascript 也是验证文件客户端的好方法 side.For javascript 正则表达式验证,您可以留意这个回答

或者如果您能够使用插件,您可以使用 jquery 验证插件

https://jqueryvalidation.org/

fields = '__all__'

来自两勺 Django 的建议:Django 1.8 的最佳实践

26.14 Don't Use ModelForms.Meta.fields = "__ all __" - This includes every model field in your model form. It’s a shortcut, and a dangerous one. It’s very similar to what we describe in section 26.13 (Don't Use ModelForms.Meta.exclude) and even with custom validation code, exposes projects to form-based Mass Assignment Vulnerabilities. We advocate avoiding this technique as much as possible, as we feel that it’s simply impossible to catch all variations of input.