python - 使用 Django 的 AWS 文件上传问题
问题描述
我已经通过 cpanel 部署了我的 django 应用程序。静态和媒体文件通过 AWS S3 正确提供。但是当我尝试上传文件/图片时,它没有上传并且没有显示错误,并使用上传文件的页面的 url 重定向到主页。主页 URL:www.example.com,上传页面 URL:www.example.com/upload。
存储桶访问是公开的。IAM 用户可以完全访问 S3 我将非常感谢您的宝贵时间和帮助。
CORS Policy
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Bucket Policy
{
"Version": "2012-10-17",
"Id": "Policy1603207554013",
"Statement": [
{
"Sid": "Stmt1603207062804",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::django-bucket/*"
},
{
"Sid": "Stmt1603207552031",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::085459706277:user/django_user"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::django-bucket/*",
"arn:aws:s3:::django-bucket"
]
}
]
}
settings.py
AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.getenv('AWS_STORAGE_BUCKET_NAME')
AWS_DEFAULT_ACL = None
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=86400'}
# s3 static settings
STATIC_LOCATION = 'static'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{STATIC_LOCATION}/'
STATICFILES_STORAGE = 'stock_app.storage_backends.StaticStorage'
# s3 public media settings
PUBLIC_MEDIA_LOCATION = 'media'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{PUBLIC_MEDIA_LOCATION}/'
DEFAULT_FILE_STORAGE = 'stock_app.storage_backends.PublicMediaStorage'
storage_backends.py
from storages.backends.s3boto3 import S3Boto3Storage
from django.conf import settings
class StaticStorage(S3Boto3Storage):
location = 'static'
default_acl = 'public-read'
class PublicMediaStorage(S3Boto3Storage):
location = 'media'
default_acl = 'public-read'
file_overwrite = False
models.py
class Upload(models.Model):
file = models.FileField(upload_to='data base')
def __str__(self):
return f'{self.file} Success'
forms.py
class UploadFileForm(forms.ModelForm):
class Meta:
model = Upload
fields = ['file']
views.py
@login_required
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
file = request.FILES['file']
output = files_to_database(file)
if not output: #checks to see if file is not already in database
form.save()
return redirect('upload')
else:
form = UploadFileForm()
return render(request, 'stock_app/upload.html', {'form': form})
解决方案
存储桶策略存在问题。在这个网站上找到了答案: https : //testdriven.io/blog/storing-django-static-and-media-files-on-amazon-s3/ 对我有用的政策是:
Bucket Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
}
]
}
推荐阅读
- reactjs - 使用 NativeBase 的 iOS 应用程序的顶部和底部黑色熨平板
- git - 为什么更改不自动转到暂存区?
- python - get_cookies() 在 Selenium 中使用 Chrome 返回带有 Whatsapp Web 的空列表
- amazon-web-services - 如何通过cloudformation在非默认vpc上创建弹性伸缩组?
- ruby-on-rails - 如何在运行 Ruby 2.7.0 时抑制 RSpec 中的警告
- python - 当按下 Flutter 中编程的按钮时,有没有办法可以运行 python 脚本?
- graphql - 如何使用 gatsby 从内容中显示媒体内容
- python - 如何从命令行使用已安装的 pip3 包?
- javascript - 在 Card 组件中居中 Avatar 组件
- python-3.x - 指定 Spark Schema 不会显示正确的显示结果