如何使用 django 应用程序在 AWS S3 中上传文件?

我在上传用户个人资料图片时遇到问题。现在,当我在 Django 管理中创建用户并从管理仪表板上传文件时,它可以正常工作,没有错误。它按照应有的方式进入我的 AWS S3 存储桶,但这显然是不可行的,我一直在寻找解决方案 3 到 4 天,但没有成功或没有任何令人满意的结果。我显然不会向用户提供仪表板访问权限。使用的数据库是MongoDB,数据库引擎是djongo。


这是我的设置.py


INSTALLED_APPS = [

    'profileupload',

    's3direct',

    'storages',

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'django.contrib.humanize',

]

STATIC_URL = '/static/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

MEDIA_URL = '/media/'

AWS_SECRET_ACCESS_KEY = 'MY_SPECIAL_KEY'

AWS_ACCESS_KEY_ID = 'MY_SPECIAL_KEY_NAME'

AWS_STORAGE_BUCKET_NAME = 'S3_BUCKET'

AWS_S3_FILE_OVERWRITE = False

AWS_DEFAULT_ACL = None

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

我的网址.py


from django.urls import path, include

from .views import signup_form

urlpatterns = [

    path('signup', signup_form, name='signup'),

]

我的模型.py


class profile(models.Model):

    profile_id = models.AutoField(primary_key=True,unique=True)

    profile_username = models.CharField(max_length=100,unique=True)

    profile_name = models.CharField(max_length=150)

    profile_email = models.EmailField(max_length=200)

    profile_create_time = models.DateField(auto_now_add=True)

    profile_dob = models.DateField()

    profile_password = models.CharField(max_length=50, null=True)

    profile_picture = models.ImageField(default='default.jpg', upload_to='profile_pics')


    def __str__(self):

        return str(self.profile_username)


另外,我想更改上传文件的名称,由 Django admin 上传的文件采用文件名,但是当我将这个应用程序公开给公众时,文件名必须正确,以避免被覆盖或具有同一个文件多次


喵喔喔
浏览 59回答 2
2回答

烙印99

正如已经提到的,一种方法是直接使用该boto3库。另一种方法是使用(也在后台使用)save的功能。django-storagesboto3如果只有1个桶:settings.py...INSTALLED_APPS = [    ...    "storages",    ...]...DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'AWS_ACCESS_KEY_ID = 'my-access-key-id'AWS_SECRET_ACCESS_KEY = 'my-secret-access-key'# Depending on the AWS account used, you might also need to declare AWS_SESSION_TOKEN as an environment variableAWS_STORAGE_BUCKET_NAME = 'my-bucket'...views.pyfrom io import BytesIOfrom django.core.files.storage import default_storagefrom rest_framework.decorators import api_viewfrom rest_framework.response import Response@api_view(('GET',))def save_file(request):    file_name = "toguro.txt"    file_content = b"I have my full 100% power now!"    file_content_io = BytesIO(file_content)    default_storage.save(file_name, file_content_io)    return Response({"message": "File successfully saved"})如果有很多桶:settings.py...INSTALLED_APPS = [    ...    "storages",    ...]...AWS_ACCESS_KEY_ID = 'my-access-key-id'AWS_SECRET_ACCESS_KEY = 'my-secret-access-key'# Depending on the AWS account used, you might also need to declare AWS_SESSION_TOKEN as an environment variable...views.pyfrom io import BytesIOfrom rest_framework.decorators import api_viewfrom rest_framework.response import Responsefrom storages.backends.s3boto3 import S3Boto3Storage# For a clear separation-of-concern, you should consider placing this code to its appropriate placeclass MyStorage1(S3Boto3Storage):    bucket_name = 'my-bucket-1'class MyStorage2(S3Boto3Storage):    bucket_name = 'my-bucket-2'@api_view(('GET',))def save_file(request):    file_name_1 = "toguro.txt"    file_name_2 = "sensui.txt"    file_content_1 = b"I have my full 100% power now!"    file_content_2 = b"I will release the S-Class demons!"    file_content_io_1 = BytesIO(file_content_1)    file_content_io_2 = BytesIO(file_content_2)    storage1 = MyStorage1()    storage2 = MyStorage2()    storage1.save(file_name_1, file_content_io_1)    storage2.save(file_name_2, file_content_io_2)    return Response({"message": "File successfully saved"})

BIG阳

好的,所以我知道了应用错误的访问键并在views.py 中接受错误的输入首先在views.py中获取正确的输入pr.profile_picture = request.POST.get('profile_picture')除了使用上述内容之外,以下内容会有所帮助:pr.profile_picture  = request.FILES["profile_picture"]另外,当我将上面的内容与单个引号一起使用时,它将不起作用,所以请记住这一点。将文件上传到S3现在将有一些其他方法来执行此操作,但同时更改文件名。我专门制作了另一个文件来处理图像并更改文件名。import boto3session = boto3.Session(    aws_access_key_id= 'secret sauce',    aws_secret_access_key = 'secret sauce')class image():    def UploadImage(name,image):        filename = name+'_picture.jpg'        imagedata = image        s3 = boto3.resource('s3')        try:            object = s3.Object('bucket sauce', filename)            object.put(ACL='public-read',Body=imagedata,Key=filename)            return True        except Exception as e:            return e上面的方法在views.py中调用ret = image.UploadImage(pr.profile_username,pr.profile_picture)将其放在 try 块中以避免错误。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python