![](/img/trans.png)
[英]Django file upload with “application/octet-stream” content-type
[英]Better Way to validate file by content-type in django
因此,我实现了以下托管的代码段:
https://djangosnippets.org/snippets/1303/
到目前为止,这是我的代码:
models.py
class Vehicle(models.Model):
pub_date = models.DateTimeField('Date Published', auto_now_add=True)
make = models.CharField(max_length=200)
model = models.CharField(max_length=200)
picture = models.FileField(upload_to='picture')
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse('recipe_edit', kwargs={'pk': self.pk})
views.py
def vehicle_list(request, template_name='vehicle/vehicle_list.html'):
if request.POST:
form = VehicleForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('vehicle_list')
else:
form = VehicleForm() # Create empty form
vehicles = Vehicle.objects.all() # Retrieve all vehicles from DB
return render(request, template_name, {
'vehicles': vehicles,
'form': form
},context_instance=RequestContext(request))
forms.py
class VehicleForm(forms.ModelForm):
class Meta:
model = Vehicle
def clean_picture(self):
content = self.cleaned_data['picture']
content_type = content.content_type.split('/')[0]
if content_type in settings.CONTENT_TYPES:
if content.size > settings.MAX_UPLOAD_SIZE:
raise forms.ValidationError('Please keep file size under %s', filesizeformat(content.size))
else:
raise forms.ValidationError('File type is not supported')
据我了解,这种方法仍然可以通过修改标头轻松地覆盖。 我要问的是,对于这种情况是否有更好的方法?
为了验证客户端给定的文件内容是否匹配给定的内容类型,您需要一个完整的数据库来描述如何检测内容类型。
但是,您可以依赖libmagic项目。 在pypi上有此库的绑定: python-magic
您需要调整VehicleForm以便进行内容类型检测:
class VehicleForm(forms.ModelForm):
class Meta(object):
model = Vehicle
def clean_picture(self):
content = self.cleaned_data['picture']
try:
content.open()
# read only a small chunk or a large file could nuke the server
file_content_type = magic.from_buffer(content.read(32768),
mime=True)
finally:
content.close()
client_content_root_type = content.content_type.split('/')[0]
file_content_root_type = file_content_type.split('/')[0]
if client_content_root_type in settings.CONTENT_TYPES and \
file_content_root_type in settings.CONTENT_TYPES:
if content.size > settings.MAX_UPLOAD_SIZE:
raise forms.ValidationError('Please keep file size under %s',
filesizeformat(content.size))
else:
raise forms.ValidationError('File type is not supported')
return content
编写这段代码是为了演示其工作原理,而不是在减少冗余代码的情况下。
我不建议您在生产代码中独自执行此操作。 我建议使用已经存在的代码。 如果您真的只需要验证图像已上传并可以查看,则建议使用ImageField表单字段。 请注意,ImageField使用枕头来确保可以打开图像。 这可能会或可能不会对您的服务器构成威胁。
还有其他几个可用的项目,它们完全实现了确保已上传某种内容类型的文件的所需功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.