Безопасная загрузка изображений в веб-приложении на Django
🖼️ 💾 Почти в любом веб-приложении есть необходимость принимать от пользователей картинки. В Django это можно делать лаконично и безопасно, используя ImageField и Pillow.
Загрузка изображений в Django
В Django есть два поля, позволяющих загружать картинки: FileField
и ImageField
. Второй вариант – специализированная версия FileField
, использующая подтверждение от библиотеки Pillow
, что файл является изображением.
Начнем с
создания моделей. Создадим файл models.py
и поместим в него следующее содержимое:
from django.db import models class Image(models.Model): title = models.CharField(max_length=200) image = models.ImageField(upload_to='images') def __str__(self): return self.title
Переменная image
– это
поле ImageField
, которое работает с API хранилища, который обеспечивает способ
хранения/извлечения, а также чтения/записи файлов.
Параметр upload_to
указывает путь, где будут храниться изображения. Для этой модели он будет соответствовать MEDIA_ROOT/images/
Также возможна установка динамических путей для изображений:
image = models.ImageField(upload_to='users/%Y/%m/%d/', blank=True)
Это позволит хранить
изображения в каталогах вида MEDIA_ROOT/users/2020/05/26
.
Установим Pillow
, выполнив следующую команду:
pip install Pillow
Чтобы Django
обслуживал медиафайлы, загруженные пользователями, добавим следующие настройки
в файл settings.py
вашего проекта:
# Основной url для управления медиафайлами MEDIA_URL = '/media/' # Путь хранения картинок MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL
– это
URL-адрес, который будет обслуживать медиафайлы, а MEDIA_ROOT
– это путь к
корневому каталогу, в котором хранятся файлы.
Добавим следующий код
в urls.py
:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('admin/', admin.site.urls), ...] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Теперь нам нужно создать форму
для модели изображения. В файл forms.py
добавим следующий код:
from django import forms from .models import Image class ImageForm(forms.ModelForm): class Meta: model = Image fields = ('title', 'image')
Это создаст форму с
полями title
и image
, которые будут отображаться в шаблонах. А сейчас создадим
шаблон для загрузки файлов. В index.html
внесем следующее:
<form method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <button type="submit">Upload</button> </form> {% if img_obj %} <h3>Succesfully uploaded : {{img_obj.title}}</h3> <img src="{{ img_obj.image.url}}" alt="connect" style="max-height:300px"> {% endif %}
Включение свойства enctype
для формы обеспечивает правильное прикрепление загруженного файла к запросу.
Напишем обработчик формы в views.py
:
from django.shortcuts import render from .forms import ImageForm def image_upload_view(request): """Process images uploaded by users""" if request.method == 'POST': form = ImageForm(request.POST, request.FILES) if form.is_valid(): form.save() # Get the current instance object to display in the template img_obj = form.instance return render(request, 'index.html', {'form': form, 'img_obj': img_obj}) else: form = ImageForm() return render(request, 'index.html', {'form': form})
Django делает всю
работу сам, а мы просто прогоняем форму через валидацию и сохраняем ее при
успешной загрузке файла. Теперь, когда обработчик готов, сопоставим все
с URL-адресом в urls.py
:
urlpatterns = [ ...... path('upload/', views.image_upload_view) ...... ]
Сохраним файлы, запустим сервер и проверим работу программы.
Заключение
Мы рассмотрели простейший вариант безопасной загрузки картинки на сервер с помощью Django. Вариант прост в реализации и понятен не только для специалистов с опытом. Удачи в обучении.