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

Django项目中如何用Python遍历AWS S3中的图片对象?

解决AWS S3环境下无法遍历媒体文件夹图片的问题

问题根源

本地环境用os.listdir()读取本地文件系统的媒体文件夹是可行的,但生产环境中媒体文件存储在AWS S3上,os.listdir()无法访问远程S3存储,因此失效。需要改用AWS S3的API来获取指定前缀(对应文件夹)下的文件列表。


解决方案1:使用Django默认存储类(推荐,适配django-storages)

如果你的项目已经配置了django-storages来对接S3,直接用Django的default_storage即可完成文件列表遍历,无需直接操作boto3:

修改视图代码

from django.conf import settings
from django.shortcuts import get_object_or_404, render
from urllib.parse import quote
from django.core.files.storage import default_storage

def carmodel(request, carmodel_id):
    carmodel = get_object_or_404(CarModel, id=carmodel_id)
    # S3中对应"文件夹"的前缀(S3无真实文件夹,靠对象键前缀区分)
    s3_prefix = f"{carmodel.title}/"
    
    # 用default_storage列出前缀下的文件:listdir返回(子文件夹列表, 文件列表)
    _, image_files = default_storage.listdir(s3_prefix)
    
    # 编码文件夹名中的特殊字符(如空格),用于构建URL
    encoded_folder_name = quote(carmodel.title)
    # 取出配置好的MEDIA_URL,确保末尾无斜杠
    media_base_url = settings.MEDIA_URL.rstrip('/')

    return render(request, 'vehicles/vehicle.html', 
                  {
                      "carmodel": carmodel, 
                      "image_folder": image_files, 
                      "folder_name": encoded_folder_name,
                      "media_url": media_base_url
                  })

修改模板代码

{% for image in image_folder %}
  <img src="{{ media_url }}/{{ folder_name }}/{{ image }}" class="slider-thumbnail">
{% endfor %}

解决方案2:直接使用boto3操作S3

如果未使用django-storages,可以直接用boto3调用S3 API:

1. 安装依赖

pip install boto3

2. 修改视图代码

import boto3
from django.conf import settings
from django.shortcuts import get_object_or_404, render
from urllib.parse import quote

def carmodel(request, carmodel_id):
    carmodel = get_object_or_404(CarModel, id=carmodel_id)
    s3_prefix = f"{carmodel.title}/"
    
    # 初始化S3客户端
    s3_client = boto3.client(
        's3',
        aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
        aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
        region_name=settings.AWS_S3_REGION_NAME
    )
    
    # 列出指定前缀下的对象
    response = s3_client.list_objects_v2(
        Bucket=settings.AWS_STORAGE_BUCKET_NAME,
        Prefix=s3_prefix
    )
    
    image_files = []
    if 'Contents' in response:
        for obj in response['Contents']:
            # 提取文件名(去掉前缀部分),跳过空的"文件夹"对象
            file_name = obj['Key'].replace(s3_prefix, '', 1)
            if file_name:
                image_files.append(file_name)
    
    encoded_folder_name = quote(carmodel.title)
    media_base_url = settings.MEDIA_URL.rstrip('/')

    return render(request, 'vehicles/vehicle.html', 
                  {
                      "carmodel": carmodel, 
                      "image_folder": image_files, 
                      "folder_name": encoded_folder_name,
                      "media_url": media_base_url
                  })

模板代码同方案1


注意事项

  • 确保AWS IAM角色/用户拥有S3存储桶的ListBucket和GetObject权限,否则无法读取文件列表和访问图片。
  • 检查Django配置中的S3参数:AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_S3_REGION_NAME、AWS_STORAGE_BUCKET_NAME必须正确配置。
  • 如果前缀下的文件超过1000个,需要处理S3的分页查询(通过ContinuationToken循环获取所有对象),上述示例代码为简化版,仅处理单次返回的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 01:33:24