在Heroku部署的Django项目中如何上传并使用图片资源?
是否可以将图片存储在PostgreSQL中
技术层面可以实现,将图片转为二进制BYTEA格式或者Base64编码后存入数据库字段即可,但完全不推荐生产环境这么操作,核心原因如下:
- 会导致数据库体积快速膨胀,大幅降低业务数据的查询、备份、迁移效率,拖垮整体服务性能
- Django原生
ImageField不支持直接存储二进制数据到数据库,需要额外自定义字段逻辑,增加开发维护成本 - 图片属于静态资源,通过数据库查询返回的响应速度远低于专门的对象存储服务,会拉长用户端图片加载耗时
Heroku部署适用的图片存储方案
Heroku的dyno文件系统是临时存储,每次部署、重启dyno时所有本地写入的文件都会被清空,本身就不支持持久化存储用户上传的静态资源,推荐使用第三方对象存储服务解决该问题:
- 可选择的存储服务包含各类公有云对象存储产品,适配Django框架的成本极低
- 你仅需安装
django-storages类的存储适配库,在项目配置文件中填写对应存储服务的密钥、存储桶等配置,指定默认文件存储后端为对象存储即可,现有Product模型代码不需要做任何修改 - 配置完成后,用户上传图片时会自动写入对象存储,
image字段保存的是对象存储的公网访问地址,可直接在前端加载使用
你当前的Product模型无需调整,参考代码如下:
class Product(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) name = models.CharField(max_length=255, blank=True, null=True) image = models.ImageField(upload_to='images', blank=True, null=True) price = models.FloatField(max_length=255, blank=True, null=True) description = models.TextField(max_length=255, blank=True, null=True) category = models.ForeignKey(Category, blank=True, on_delete=models.CASCADE) seller = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.name
内容的提问来源于stack exchange,提问作者Aleksa
相关产品推荐
相关产品推荐

