简体   繁体   English

如何使用 S3Boto3Storage 在 django 中上传图像,其中路径是从 django 中的视图动态设置的

[英]How to upload an image in django using S3Boto3Storage where the path is set dynamically from the view in django

I'm wanting to save images to an S3 bucket using the session_key as the directory inside the bucket, in django.我想在 django 中使用 session_key 作为存储桶内的目录将图像保存到 S3 存储桶。

I have created a test page that uploads an image to a set location in the bucket but don't know how to use the session_key to set the upload location dynamically.我创建了一个测试页面,将图像上传到存储桶中的设置位置,但不知道如何使用 session_key 动态设置上传位置。

I've looked at the docs for django-storages and I can see a way to do this if it wasn't for the fact that I am using a ModelForm .我查看了django-storages的文档,如果不是因为我使用的是ModelForm ,我可以看到一种方法。

Here is the code I have (I have omitted my settings.py with the bucket name and credentials):这是我的代码(我省略了带有存储桶名称和凭据的 settings.py):

storage_backends.py

from storages.backends.s3boto3 import S3Boto3Storage

class TestS3MediaStorage(S3Boto3Storage):
    location = 'dev/'
    default_acl = 'public-read'
    file_overwrite = False

models.py

from .storage_backends import TestS3MediaStorage

class TestS3Upload(models.Model):
    uploaded_at = models.DateTimeField(auto_now_add=True)
    file = models.FileField(storage=TestS3MediaStorage())

forms.py

from .models import TestS3Upload

class TestS3UploadForm(forms.ModelForm):

    class Meta:
        model = TestS3Upload
        fields = ['file']

views.py

from django.shortcuts import render
from django.http import HttpResponse

from .forms import TestS3UploadForm

def test_s3_upload(request):

    # create session if it doesn't already exist
    if not request.session.session_key:
        request.session.create()

    # not quite sure how to use this to set upload destination
    session_key = request.session.session_key

    if request.method == 'POST':

        form = TestS3UploadForm(request.POST, request.FILES)

        if form.is_valid():
            form.save()
            return HttpResponse("upload successful!")
    else:
        form = TestS3UploadForm()

    return render(
        request,
        'uploader/test_s3_upload.html',
        {
            'form': form
        }
    )

test_s3_upload.html

<h1>Test S3 file upload</h1>
<form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Upload photo to S3 Bucket</button>
</form>

显示上传图片的模板页面截图

When I run my code and upload an image, for example car.jpg , it uploads successfully but the path inside the S3 bucket is当我运行我的代码并上传图像时,例如car.jpg ,它成功上传,但 S3 存储桶内的路径是

<bucket-name>/dev/car.jpg

and i want而且我要

<bucket-name>/dev/<session-key>/car.jpg

The packages needed are boto3 and django-storages in case anyone who wants to help answer needs to know.需要的包是boto3django-storages storages,以防任何想帮助回答的人需要知道。

I have figured out a way to upload an image/file to s3 to a directory using the session key.我想出了一种使用 session 密钥将图像/文件上传到 s3 到目录的方法。 It also works for uploading a file in general, not just s3.它也适用于一般上传文件,而不仅仅是 s3。

First I added an attribute to the model to store the session key.首先,我向 model 添加了一个属性来存储 session 密钥。

class TestS3Upload(models.Model):
    session_key = models.CharField(max_length=50, null=False, blank=False)
    ...

Then I included a hidden field on the modelform that I pre-populated with the session_key value in the view.然后我在模型表单上包含了一个隐藏字段,我在视图中预先填充了session_key值。

forms.py

class TestS3UploadForm(forms.ModelForm):

    class Meta:
        model = TestS3Upload
        fields = ['file', 'session_key']
        widgets = {'session_key': forms.HiddenInput()}

views.py

def test_s3_upload(request):
    # create session if it doesn't already exist
    if not request.session.session_key:
        request.session.create()

    session_key = request.session.session_key
    ...
    form = TestS3UploadForm(initial={'session_key': session_key})

Then I created a function in my models.py that returns a path using the session_key from the model and set the model's file field upload_to attribute to this function然后我在我的models.py中创建了一个 function ,它使用 model 中的 session_key 返回一个路径,并将模型的文件字段upload_to属性设置为此 ZC1C425268E68385D1AB5074C17A4

...
import os

def upload_to_session_key_dir(instance, filename):
    return os.path.join(instance.session_key, filename)

class TestS3Upload(models.Model):
    session_key = models.CharField(max_length=50, null=False, blank=False)
    uploaded_at = models.DateTimeField(auto_now_add=True)

    file = models.FileField(upload_to=upload_to_session_key_dir)

When saving the form now it uploads the file inside a directory with the session_key.现在保存表单时,它会使用 session_key 将文件上传到目录中。

final views.py最终views.py

from django.shortcuts import render
from django.http import HttpResponse
from .forms import TestS3UploadForm
from .models import TestS3Upload

def test_s3_upload(request):

    # create session if it doesn't already exist
    if not request.session.session_key:
        request.session.create()

    session_key = request.session.session_key

    if request.method == 'POST':

        form = TestS3UploadForm(request.POST, request.FILES)

        if form.is_valid():
            form.save()

            filename = "{}/{}".format(session_key, form.cleaned_data['file'].name)
            s3_upload_path = TestS3Upload.objects.get(file=filename).file.url

            return HttpResponse("Image successfully uploaded to bucket at location: {}".format(s3_upload_path))
    else:
        form = TestS3UploadForm(initial={'session_key': session_key})

    return render(
        request,
        'upload/test_s3_upload.html',
        {
            'form': form
        }
    )

The template for the view test_s3_upload.html remained the same.视图 test_s3_upload.html 的模板保持不变。

上传成功消息,其中包含上传文件的完整 url 路径

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 s3boto3storage 和 django 读取和写入不同的 S3 存储桶 - Reading and Writing to different S3 buckets with s3boto3storage and django Django-storages S3Boto3Storage在读取时发出HEAD和GET请求 - Django-storages S3Boto3Storage makes HEAD and GET requests on read Django:使用PIL,Amazon S3和Boto调整图像大小并上传 - Django: Image Resize and Upload with PIL, Amazon S3 and Boto 如何将图像上传到文件夹并将其路径传递给 Django 中的视图函数? - How to upload an image to a folder and pass its path to a view function in django? 使用Python / Boto / Django直接上传到S3构建策略 - Direct Upload to S3 Using Python/Boto/Django to Construct Policy django aws S3动态定义上传文件路径和文件 - django aws S3 define upload file path and file dynamically 使用django-storages boto3将文件动态上传到不同的s3存储桶中 - Upload files dynamically into different s3 buckets with django-storages boto3 使用Django + Fineuploader + boto从S3删除文件 - Deleting a file from S3 using Django + Fineuploader + boto 如何为Django应用程序设置图片上传根目录 - How to set image upload root for django application Boto3 + Django + S3 解码 base64 图像上传不起作用 - Boto3 + Django + S3 decoded base64 Image Upload not working
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM