Uploading Files to AWS S3 with Python and Django
介绍
为了建立更多的交互式网站,我们不仅将信息传递给用户,还允许他们上传自己的数据。 这为我们的网站为最终用户提供了更多机会和更多方式。
通过允许用户上传文件,我们可以允许他们与他人共享照片,视频或音乐,或者将其备份以保存。 我们还可以提供功能来管理文件并将其通过网站转换为其他格式,而不是安装本机应用程序。
社交媒体在全球范围内的兴起可以归因于用户上传文件的能力,这些能力主要以图像和视频的形式供其他用户查看,也可以作为一种通信手段。 通过使用户能够将文件上传到网站和平台,通信手段得到了增强,信息现在可以以许多不同的格式传播。
在本文中,我们将探讨Django如何处理文件上传,以及如何利用云存储来利用和扩展此功能来满足我们的需求。
Django如何处理文件存储
Django不仅允许我们将概念转变为Web应用程序,而且还为我们提供了处理文件的功能,并允许用户将文件上传到我们的Web应用程序以进行进一步的交互。 通过表单,用户可以将文件附加到他们的请求中,并将文件上传并存储在我们的后端服务器中。
在保存文件之前,先将其临时存储在某个位置,然后再进行处理并存储在预期的最终位置。 例如,如果上传的文件小于2.5MB,则该文件的内容将存储在内存中,然后在处理文件时完成所有操作后将其写入磁盘。
这样可以快速处理小文件。 对于大于2.5MB的文件,在接收数据时首先将它们写入一个临时位置,然后在处理完成后将文件移至其最终目的地。
Django中的文件行为可以通过各种设置进行自定义,例如
其他设置可以在官方Django文档的本部分中找到。
我们可以在哪里存储文件?
在基于Django的Web应用程序中,我们可以将上传的文件存储在各个不同的位置。 我们可以将它们存储在部署Django代码的我们自己的服务器上,也可以将它们发送到可能在其他地方设置用于存储目的的其他服务器。
为了降低服务器维护成本并提高性能,我们还可以选择不将上传的文件存储在我们自己的服务器上。 在这种情况下,我们可以将它们移交给其他托管存储提供商,例如AWS,Azure或OneDrive。
有几个软件包可以让我们与我们提到的各种服务提供商提供的API进行交互。 它们包括:
Django-Storages使我们能够将上传的文件存储到AWS Simple Storage Service(S3),Dropbox,OneDrive,Azure和Digital Ocean。
Django-S3-Storage,我们可以通过它直接将文件上传到Amazon S3
Django-Cumulus,它使我们能够与Rackspace进行交互以满足存储需求
其他包括Django-Dropbox,Django-Storage-Swift和Django-Cloudinary-Storage。 在这里可以找到更多
在本文中,我们将使用Django-s3direct包将文件存储在AWS S3上。
我们的应用程序-Django Drive
我们将使用Django构建一个Web应用程序,在其中将上载内容供最终用户查看。 这将通过使用框架附带的Django管理界面来实现。
我们的网站将用于销售汽车,并在其上显示详细信息并添加正在销售的汽车的图像或视频。
待售汽车的图像或视频将存储在S3中。 为简便起见,我们暂时不实施用户注册或登录。
建立
我们将使用Pipenv来设置和管理隔离的环境,在该环境中,我们将通过运行以下命令以使用Python3进行设置来构建Django应用程序:
1 | $ pipenv install --three |
设置好环境后,我们现在可以安装Django和Django-s3direct来处理向S3的文件上传:
1 | $ pipenv install django django-s3direct |
在开始实现应用程序的核心功能之前,Django提供了一组命令来引导我们的项目。 我们的Django驱动器项目将只有一个应用程序,这将是本文的重点。 为此,我们运行以下命令:
1 2 | $ django-admin startproject django_drive && cd django_drive $ django-admin startapp django_drive_app |
我们设置的最后一步是通过运行
1 | $ python manage.py migrate |
通过运行命令
由于我们将文件上传到AWS S3,因此我们需要为演示目的设置一个免费的AWS账户。 设置完成后,我们可以导航到S3仪表板并创建一个包含我们上传内容的新存储桶。
为了使
接下来,我们将以下内容添加到我们的
1 2 3 4 5 6 7 8 9 10 11 12 | AWS_ACCESS_KEY_ID = 'aws-access-key-id' AWS_SECRET_ACCESS_KEY = 'secret-access-key' AWS_STORAGE_BUCKET_NAME = 'name-of-the-bucket' AWS_S3_REGION_NAME = 'name-of-the-region' AWS_S3_ENDPOINT_URL = 'https://s3.amazonaws.com' S3DIRECT_DESTINATIONS = { 'primary_destination': { 'key': 'uploads/', 'allowed': ['image/jpg', 'image/jpeg', 'image/png', 'video/mp4'], }, } |
注意:有关设置
我们还需要在
1 2 3 4 5 6 7 8 | from django.urls import path, include urlpatterns = [ ... path('', include('django_drive_app.urls')), path('s3direct/', include('s3direct.urls')), ... ] |
实作
我们将从为汽车数据创建模型开始,该模型将显示给最终用户。 该模型还将定义在将汽车添加到平台时将在管理仪表板上输入的信息。 车型如下:
1 2 3 4 5 6 7 8 9 10 11 12 | from django.db import models from s3direct.fields import S3DirectField class Car(models.Model): name = models.CharField(max_length=255, blank=False, null=False) year_of_manufacture = models.CharField(max_length=255, blank=False, null=False) price = models.CharField(max_length=255, blank=False, null=False) image = S3DirectField(dest='primary_destination', blank=True) video = S3DirectField(dest='primary_destination', blank=True) def __str__(self): return f"{self.name} ({self.year_of_manufacture}) - {self.price}" |
对于每辆汽车,我们将存储其名称,制造年份,价格以及图像或视频。 创建模型之后,让我们进行迁移以在数据库中创建表,该表将通过运行以下命令来保存我们的数据:
1 2 | $ python manage.py makemigrations $ python manage.py migrate |
由于我们将使用Django管理控制台来管理平台上的汽车,因此我们需要在
1 2 3 4 | from django.contrib import admin from.models import Car admin.site.register(Car) |
然后,我们需要通过运行以下命令并按照提示来创建负责添加汽车的超级用户:
1 2 | $ python manage.py createsuperuser $ python manage.py runserver |
重新启动服务器后,我们现在可以导航到
这是我们用来添加汽车及其详细信息的表格:
保存汽车后,我们可以在AWS控制台的S3存储桶中找到上传的图像。 这意味着我们的文件已上传到AWS。
现在,我们将创建一个视图,以向我们的网站的最终用户显示汽车及其数据,并显示与每辆汽车相关的图像或视频。 我们将从在
1 2 3 4 5 6 7 8 9 10 11 | from django.shortcuts import render from django.views.generic import TemplateView from .models import Car class CarView(TemplateView): template_name = 'django_drive_app/cars.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['cars'] = Car.objects.all() return context |
在此视图中,我们使用基于类的Django视图来呈现HTML文件以显示我们的汽车。 在我们看来,我们运行查询以获取存储在数据库中的所有汽车。
接下来,让我们创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <!DOCTYPE html> <html> <head> <title>Django Drive</title> </head> <body> <h3>Welcome to Django Drive. </h3> <p>Here are the current cars available for sale: </p> <div class="cars-container"> {% for car in cars %} <div class="car"> <p> {{ car.name }} ({{ car.year_of_manufacture }}) Price: {{ car.price }} </p> <!-- if the car has an image attached --> {% if car.image %} <img src="{{ car.image }}" height="200" width="400"/> {% endif %} <!-- If the car has a video --> {% if car.video %} <video width="320" height="240" controls> <source src="{{ car.video }}" type="video/mp4"> Your browser does not support the video tag. </video> {% endif %} </div> {% endfor %} </div> </body> </html> |
放置好视图和模板后,让我们通过创建
1 2 3 4 5 6 | from django.conf.urls import url from .views import CarView urlpatterns = [ url(r'^cars/$', CarView.as_view(), name="cars"), ] |
我们导入视图并添加URL条目以将端点映射到将渲染汽车的视图。 当我们重新启动服务器并导航到
如我们所见,我们创建了带有附加图像和视频的汽车,并将其上传到AWS的S3服务。 从AWS提取后,相同的图像和视频已在我们的Web应用程序中呈现。
结论
在本文中,我们创建了一个简单的Django应用程序,允许管理员通过Django管理仪表板将文件上传到AWS S3。 我们在目标网页上的S3上托管了上传的文件,包括用户希望购买或观看的汽车的视频和图像。
我们使用了
该项目的源代码可在GitHub上找到。