![](/img/trans.png)
[英]Reading and Writing to different S3 buckets with s3boto3storage and django
[英]How to upload an image in django using S3Boto3Storage where the path is set dynamically from the view in django
我想在 django 中使用 session_key 作為存儲桶內的目錄將圖像保存到 S3 存儲桶。
我創建了一個測試頁面,將圖像上傳到存儲桶中的設置位置,但不知道如何使用 session_key 動態設置上傳位置。
我查看了django-storages
的文檔,如果不是因為我使用的是ModelForm
,我可以看到一種方法。
這是我的代碼(我省略了帶有存儲桶名稱和憑據的 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>
當我運行我的代碼並上傳圖像時,例如car.jpg
,它成功上傳,但 S3 存儲桶內的路徑是
<bucket-name>/dev/car.jpg
而且我要
<bucket-name>/dev/<session-key>/car.jpg
需要的包是boto3
和django-storages
storages,以防任何想幫助回答的人需要知道。
我想出了一種使用 session 密鑰將圖像/文件上傳到 s3 到目錄的方法。 它也適用於一般上傳文件,而不僅僅是 s3。
首先,我向 model 添加了一個屬性來存儲 session 密鑰。
class TestS3Upload(models.Model):
session_key = models.CharField(max_length=50, null=False, blank=False)
...
然后我在模型表單上包含了一個隱藏字段,我在視圖中預先填充了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})
然后我在我的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)
現在保存表單時,它會使用 session_key 將文件上傳到目錄中。
最終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
}
)
視圖 test_s3_upload.html 的模板保持不變。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.