dvt*_*tan 11 django django-models
到目前为止,我一直将我的图像文件名存储在CharField中,并将实际文件直接保存到S3.这对我自己的用法来说是个很好的解决方案.我想重新考虑使用ImageField,因为现在将有其他用户和文件输入验证是合适的.
在阅读了文档和FileField 的源代码(看起来基本上是ImageField减去Pillow检查和维度字段更新功能)之后,我有几个问题没有得到完全解答.
1)为什么要使用ImageField?或者更确切地说,为什么要使用FileField?当然,它便于快速简便的表单,方便插入Django模板.但是有没有实质性的原因,例如.它是否明显受到攻击和恶意上传的保护?
2)如何写入字段文件?如果文件可以被读取instance.imagefield(或者是instance.imagefield.file?)是正确的,如果我想写它,我可以简单地执行以下操作吗?
@receiver(pre_save, sender=Image)
def pre_save_image(sender, instance, *args, **kwargs):
instance.imagefield = process_image(instance.imagefield)
Run Code Online (Sandbox Code Playgroud)
3)如何尝试使用特定文件名保存,如果随机生成的文件名已经存在,请使用新文件名再次尝试?例如我现在用我的代码执行此操作,如何使用ImageField完成?我想在模型层执行此操作,因为如果我在视图层重复尝试,则pre_save处理将再次运行,这是贫民窟(即使它不太可能在服务的生命周期中进行第二次尝试) .
for i in range(tries):
try:
name = generate_random_name()
media_storage.save(name + '.jpg', ContentFile(final_bytes))
break
except:
pass
Run Code Online (Sandbox Code Playgroud)
4)在models.py pre_save和signal 以及post_save实际模型中save(),如何判断文件是否随请求一起传入?即我想知道是否要保存新图像,或者是否没有图像(对象中的某些其他字段正在更新且图像本身保持不变).
dka*_*mer 13
我没有看到FileField或ImageField在今天你所做的事情上有任何优势.事实上,正如我所看到的,处理上传的正确/现代/可扩展方式是让客户端(浏览器)直接将文件上传到S3.
如果操作正确(从安全角度来看),此方案允许您以令人难以置信的方式进行扩展,而无需在您身边添加更多计算机电源.例如,考虑100个人同时上传图片.您的服务器需要接收所有这些数据,只能将其再次上传到S3.另一方面,您可以同时上传1000人,我可以向您保证AWS可以处理它.您的服务器只需要处理URL的签名,这是一项很少的工作.
看一下fine-uploader,作为一种很好的技术来处理有效上传到s3(加载块,错误检查等):http://docs.fineuploader.com/endpoint_handlers/amazon-s3.html.谷歌"django fineuploader"为Django寻找示例应用程序.
在我的例子中,我使用了一个带有一对CharFields(bucket,key)的模型以及一些特定于我的应用程序的其他东西.我的数据流如下:
get_original_url()和和之类的函数get_thumbnail_url()),因此在上传之后,我的模板很容易获得签名的read-onlly URL.简而言之,您可以根据需要实施自己的Fineuploader版本,或者使用许多替代方案,但假设您遵循AWS方面建议的安全最佳实践(例如,创建一个仅具有客户端写入权限的特殊IAM,甚至如果您使用的是签名URL),这个IMO是处理上传的最佳方法,特别是如果您使用S3或类似文件来存储这些文件.
很抱歉,如果我只回答问题1,但如果您接受我的答案1,则问题2和3不适用.
它方便快速简单的表单,也方便插入到 Django 模板中。
但是是否有任何实质性的原因,例如。它是否明显可以防止漏洞利用和恶意上传?
是的。我敢说您自己的代码也可能会这样做,但是对于新手来说,使用 FileField 可能会确保您的重要系统文件不会被恶意上传覆盖。
在您的情况下,您需要使用特殊的存储后端,以便可以直接写入 Amazon S3。如您所知,FileFile 和 ImageField 的存储后端是可插入的。这是一个示例插件:` http://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html
有示例代码演示了如何写入。所以我不会进入那个。`
ImageField 和 FileField 会自动为您处理这个问题。如果旧文件名存在,它将创建一个新文件名。在我的答案的代码在这里做到了自动,当我把它叫做一遍又一遍。这里有一些示例文件名产生(输入是 bada.png)
"4", "media/bada.png"
"5", "media/bada_aH0gV7t.png"
"7", "media/bada_XkzthgK.png"
"8", "media/bada_YzZuwDi.png"
"9", "media/bada_wpkasI3.png"
Run Code Online (Sandbox Code Playgroud)
你的instance.pk将是无
如果这是对现有文件的修改,则将设置 PK。
如果这是一个新的图片上传 pre_save
| 归档时间: |
|
| 查看次数: |
8176 次 |
| 最近记录: |