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 验证插件
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.
我有一个包含文件字段的模型。我想将其限制为 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 验证插件
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.