[英]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.需要的包是
boto3
和django-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 的模板保持不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.