如何使用Django Rest框架向AWS S3上传文件
文件上传和下载是网络上执行最多的一些操作。随着基于云的解决方案的兴起,公司正在从内部解决方案转移到云存储。几个原因是其更便宜的成本和便利性。
本文将演示如何使用Django Rest框架将用户生成的文件上传到Amazon S3。
前提条件
如果读者能够熟练使用Django和Django Rest框架,那么对跟随这篇文章会有帮助。
什么是AWS S3?
AWS S3是亚马逊网络服务简单存储服务(AWS S3)的首字母缩写。它是亚马逊为对象存储提供的一项基于云的服务。
对象存储是一种存储类型,其中项目被作为数据对象处理。与传统的文件系统层次结构中的文件存储方法相反。
在传统的文件系统中,存储的基本单位是一个 "文件"。在AWS S3中,存储的基本单位被称为 "桶"。
AWS控制台和AWS的可用SDK被用来访问桶。这些SDK有支持的流行语言,如Python和PHP。
使用AWS S3有几个优点。
这些优势包括。
- 可扩展性
- 高性能
- 审计能力
- 安全性
- 成本效益高
- 约99.999%的可用性(正常运行时间)。
AWS S3可以作为一个备份和灾难恢复工具,也可以用于数据分析。
在本指南中,我们将使用Django Rest框架上传用户生成的文件。
构建一个简单的Django Rest API应用程序
我们将创建一个名为Dropboxer的新Django项目。Dropboxer是一个简单的文件存储应用程序。
执行下面的命令来设置该项目。
pip install django
pip install djangorestframework
django-admin startproject dropboxer
cd dropboxer
python manage.py startapp uploader
文件夹结构看起来像下面的结构。
- dropboxer
- uploader
- manage.py
在settings.py中添加新的应用程序到INSTALLED_APPS。
…
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 3rd party apps
'rest_framework',
# local apps
'uploader', # new
]
…
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
将下面的代码片段添加到dropboxer
项目目录下的urls.py
文件中。
from django.conf import settings # new
from django.conf.urls.static import static # new
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
在uploader
应用程序中创建serializers.py
和urls.py
文件。
在models.py
文件中,我们创建一个简单的模型,代表一个单一的文件。
from django.db import models
class DropBox(models.Model):
title = models.CharField(max_length=30)
document = models.FileField(max_length=30)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name_plural = 'Drop Boxes'
在serializers.py
文件中添加下面的代码片断。
from rest_framework import serializers
from .models import DropBox
class DropBoxSerializer(serializers.ModelSerializer):
class Meta:
model = DropBox
fields = '__all__'
在uploader/views.py
。
from rest_framework import viewsets, parsers
from .models import DropBox
from .serializers import DropBoxSerializer
class DropBoxViewset(viewsets.ModelViewSet):
queryset = DropBox.objects.all()
serializer_class = DropBoxSerializer
parser_classes = [parsers.MultiPartParser, parsers.FormParser]
http_method_names = ['get', 'post', 'patch', 'delete']
在uploader/urls.py
。
from rest_framework.routers import SimpleRouter
from .views import DropBoxViewset
router = SimpleRouter()
router.register('accounts', DropBoxViewset)
urlpatterns = router.urls
在uploader/admin
中。
from django.contrib import admin
from .models import DropBox
admin.site.register(DropBox)
在dropboxer/urls.py
中。
...
from django.urls import path, include # new
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('rest_framework.urls')), # new
path('', include('uploader.urls')), # new
]
为了从我们上面创建的模型在数据库中创建一个表,执行下面的命令。
python manage.py makemigrations
python manage.py migrate
通过执行下面的命令启动开发服务器。
python manage.py runserver
在浏览器上导航到账户。我们在媒体文件夹中找到上传的样本文件。
这个样本文件是我们通过浏览器上的API上传时创建的,如下图所示。
将AWS S3整合到Django API应用程序中
我们有一个工作的应用程序API端点。你需要一个AWS账户来启用AWS S3与你的Django应用程序的集成。
如果你还没有账户,请注册,如果你有一个现有的AWS账户,请登录。
搜索S3。
点击 "创建桶"按钮。
为你的S3桶提供一个全球通用的唯一名称。
在发现一个不存在的名字之前,命名一个AWS S3桶可能需要一些尝试和错误。
保持默认选项,点击创建桶。
你将被重定向到AWS S3控制台,现在显示新创建的桶。
我们已经成功创建了一个AWS S3桶。回顾一下,在桶的创建过程中,公众对S3桶的访问被阻止了。
为了从我们的应用程序访问创建的桶,我们将需要使用AWS IAM获得访问权。AWS IAM是身份和访问管理的首字母缩写。
它用于提供对AWS资源的权利和特权的访问。目前,我们只能通过控制台访问S3桶。
AWS允许通过用户和角色来访问其资源,如AWS S3。
使用AWS搜索栏搜索IAM。
在IAM侧面菜单上点击用户。
在IAM用户仪表板上点击添加用户。
提供一个用户名并勾选程序性访问框。
在设置权限中,选择 "直接附加现有策略"并勾选AWSS3FullAcess框。
在创建用户之前,点击一下并审查你的选择。
创建成功后,它生成了一个AWS访问和秘密密钥。
在完成之前存储AWS秘钥,因为秘钥不会再显示。
一旦完成,我们可以在IAM用户仪表板上查看新创建的AWS用户。
在这篇文章中,我们将使用Django-storages来连接AWS S3桶。
Django-storages是一个为Django框架定制的存储后端集合。我们将使用Django-storages包中的AWS S3集成。
通过pip将django-storages安装到Django应用程序中。
pip install django-storages
在settings.py中加入下面的代码片段。
...
AWS_ACCESS_KEY_ID = <YOUR AWS ACCESS KEY>
AWS_SECRET_ACCESS_KEY = <YOUR AWS SECRET KEY>
AWS_STORAGE_BUCKET_NAME = <YOUR AWS S3 BUCKET NAME>
AWS_S3_SIGNATURE_VERSION = 's3v4'
AWS_S3_REGION_NAME = <YOUR AWS S3 BUCKET LOCATION>
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
AWS_S3_VERIFY = True
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_ACCESS_KEY_ID
:是IAM用户的关键标识符。它以 "AK****"开头。
AWS_SECRET_ACCESS_KEY
: 是生成的40个字母数字字符。
AWS_S3_REGION_NAME
: 指的是S3控制台仪表板中的AWS区域。例如:us-east-1,eu-west-2。
AWS_S3_SIGNATURE_VERSION
: 是用于生成预签名URL的签名版本。AWS S3桶需要该签名来授予访问权。
AWS_S3_FILE_OVERWRITE
:当设置为True
,AWS S3会覆盖一个具有相同名称和格式的文件。如果设置为False
,AWS将独特的字符串附加到新上传的文件名。它不会覆盖现有的文件。
通过执行下面的命令重新启动开发服务器。
python manage.py runserver
在浏览器上,导航到localhost并重新尝试上传一个样本文件。
点击document
领域中的链接。注意链接现在有 "s3.amazon**"。你将能够访问该文件。这里,上传的文件标题为 "Big O Cheatsheet"。
总结
在这篇文章中,我们创建了一个AWS S3桶,并给IAM用户分配了对AWS S3桶的完全访问权。我们从我们的Django Rest API应用程序中使用访问密钥和AWS秘密密钥将文件上传到AWS S3桶中。