gpt4 book ai didi

javascript - 直接到 S3 文件上传 Django 和 Heroku

转载 作者:行者123 更新时间:2023-11-29 18:51:32 25 4
gpt4 key购买 nike

我正在尝试在 Django 中设置直接到 s3 上传以获取更大的音频文件。我基本上遵循了 Heroku 的 Direct To S3 教程 https://devcenter.heroku.com/articles/s3-upload-python它更适合 Flask。我也找不到 Django 调试所指的获取请求。预先感谢您的帮助。

我收到以下错误:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/sign-s3/?file_name=piano.wav&file_type=audio/wav

Django Version: 2.0
Python Version: 3.6.5
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sitemaps',
'django.contrib.sites',
'crispy_forms',
'tinymce',
'storages',
'ckeditor',
'ckeditor_uploader',
'main',
'contact',
'accounts',
'events',
'news',
'project_settings',
'django_countries',
'publications',
'event_tracker',
'event_signup']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/Users/Tommy/anaconda3/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)

File "/Users/Tommy/anaconda3/lib/python3.6/site-packages/django/utils/deprecation.py" in __call__
97. response = self.process_response(request, response)

File "/Users/Tommy/anaconda3/lib/python3.6/site-packages/django/middleware/clickjacking.py" in process_response
26. if response.get('X-Frame-Options') is not None:

Exception Type: AttributeError at /sign-s3/
Exception Value: 'str' object has no attribute 'get'

Views.py 文件:

def committee_new_podcast(request, id):
template = "main/add_podcast.html"

committee = get_object_or_404(Committee, comm_id=id)

if request.user.is_authenticated:
if Member.objects.filter(user=request.user).exists():
member = Member.objects.get(user=request.user)

if CommitteeMember.objects.filter(Q(is_chair=True) | Q(is_deputy=True)).filter(abila=member, comm=committee.comm_id) or request.user.is_staff:
if request.method == 'POST':
form = CommitteePodcastForm(request.POST, request.FILES)

if form.is_valid():
instance = form.save(commit=False)
instance.comm_id = committee
instance.member = member
instance.sound = request.form['avatar-url']
instance.save()
messages.success(request, 'Committee Podcast Was Created',
"alert alert-success alert-dismissible")

else:
form = CommitteePodcastForm()

else:
form = ''
messages.success(request, 'You must be a chair or deputy to access this page.',
"alert alert-danger alert-dismissible")
elif request.user.is_staff:
if request.method == 'POST':
form = CommitteePodcastForm(request.POST, request.FILES)

if form.is_valid():
instance = form.save(commit=False)
instance.comm_id = committee
instance.save()
messages.success(request, 'Committee Podcast Was Created',
"alert alert-success alert-dismissible")
else:
form = CommitteePodcastForm()
else:
form = ''
pass
else:
form = ''
messages.success(request, 'You must be logged in to access this page.',
"alert alert-danger alert-dismissible")

context = {
'committee': committee,
'form': form,
}

return render(request, template, context)


def sign_s3(request):
S3_BUCKET = settings.AWS_STORAGE_BUCKET_NAME

file_name = request.GET.get('file_name')
file_type = request.GET.get('file_type')

s3 = boto3.client('s3')

presigned_post = s3.generate_presigned_post(
Bucket = S3_BUCKET,
Key = file_name,
Fields = {"acl": "public-read", "Content-Type": file_type},
Conditions = [
{'acl': "public-read"},
{"Content-Type": file_type}
],
ExpiresIn = 3600
)

return json.dumps({
'data': presigned_post,
'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name),
})

Javascript:

<script>
(function() {
document.getElementById('file_input').onchange = function(){
var files = document.getElementById('file_input').files;
var file = files[0];
if(!file){
return alert("No file selected.");
}
getSignedRequest(file);
}
})();

function getSignedRequest(file){
var xhr = new XMLHttpRequest();
xhr.open("GET", "/sign-s3?file_name="+file.name+"&file_type="+file.type);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
var response = JSON.parse(xhr.responseText);
uploadFile(file, response.data, response.url);
}
else{
alert("Could not get signed URL.");
}
}
}
xhr.send();
}

function uploadFile(file, s3Data, url){
var xhr = new XMLHttpRequest();
xhr.open("POST", s3Data.url);

var postData = new FormData();
for(key in s3Data.fields){
postData.append(key, s3Data.fields[key]);
}
postData.append('file', file);

xhr.onreadystatechange = function() {
if(xhr.readyState === 4){
if(xhr.status === 200 || xhr.status == 204){
document.getElementById("sound-url").value = url;
}
else {
alert("Could not upload file.");
}
}
}
xhr.send(postData)
}
</script>

最佳答案

我明白了,我应该一直使用 HttpResponse 来返回 JSON 数据。

def sign_s3(request):
S3_BUCKET = settings.AWS_STORAGE_BUCKET_NAME

file_name = request.GET.get('file_name')
file_type = request.GET.get('file_type')

s3 = boto3.client('s3')

presigned_post = s3.generate_presigned_post(
Bucket = S3_BUCKET,
Key = file_name,
Fields = {"acl": "public-read", "Content-Type": file_type},
Conditions = [
{'acl': "public-read"},
{"Content-Type": file_type}
],
ExpiresIn = 3600
)

data = json.dumps({
'data': presigned_post,
'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name),
})

return HttpResponse(data, content_type='json')

关于javascript - 直接到 S3 文件上传 Django 和 Heroku,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51218970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com