You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django FileField对接S3存储时文件名自动URL编码如何关闭?

问题原因

你遇到的是典型的URL二次编码问题,本质是Django的FileField在生成访问URL时,默认会对存储的文件路径做URL编码处理:

  • 数据库中存储的路径已经包含编码后的字符%40(对应字符@)
  • 生成URL时,Django会把路径中的%当作普通字符编码为%25,最终拼接后就得到了%2540

解决办法

方法1:自定义S3存储类,重写URL生成逻辑(最通用)

继承你当前使用的S3存储类,重写url方法,跳过默认的路径编码步骤:

from storages.backends.s3boto3 import S3Boto3Storage

class UnescapedS3Storage(S3Boto3Storage):
    def url(self, name, parameters=None, expire=None):
        # 直接调用父类方法后替换被二次编码的%字符即可
        url = super().url(name, parameters, expire)
        return url.replace('%25', '%')

然后把模型字段的storage参数替换为你自定义的存储类实例:

image_file = models.FileField(storage=UnescapedS3Storage(), max_length=512, blank=True)

方法2:序列化器层面手动处理返回值

如果不想修改全局存储逻辑,也可以在DRF序列化器中自定义字段的返回值,直接读取数据库中存储的原始路径拼接成访问地址:

from rest_framework import serializers

class YourModelSerializer(serializers.ModelSerializer):
    image_file = serializers.SerializerMethodField()

    def get_image_file(self, obj):
        if obj.image_file:
            # 替换为你的S3 Bucket公开访问域名前缀
            return f"https://your-s3-bucket-domain.com/{obj.image_file.name}"
        return None

    class Meta:
        model = YourModel
        fields = '__all__'

方法3:配置django-storages参数关闭编码(高版本支持)

如果你使用的是1.12及以上版本的django-storages,直接在项目settings.py中添加配置即可关闭默认编码逻辑:

AWS_S3_ESCAPE_URLS = False

注意:低版本django-storages没有该配置项,不支持该方法


内容的提问来源于stack exchange,提问作者user1663023

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 10:45:08