Безопасная загрузка изображений в веб-приложении на Django

🖼️ 💾 Почти в любом веб-приложении есть необходимость принимать от пользователей картинки. В Django это можно делать лаконично и безопасно, используя ImageField и Pillow.

Загрузка изображений в Django

В Django есть два поля, позволяющих загружать картинки: FileField и ImageField. Второй вариант – специализированная версия FileField, использующая подтверждение от библиотеки Pillow, что файл является изображением.

Начнем с создания моделей. Создадим файл models.py и поместим в него следующее содержимое:

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:

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 добавим следующий код:

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. Вариант прост в реализации и понятен не только для специалистов с опытом. Удачи в обучении.

Источники

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

admin
11 декабря 2018

ООП на Python: концепции, принципы и примеры реализации

Программирование на Python допускает различные методологии, но в его основе...
admin
28 июня 2018

3 самых важных сферы применения Python: возможности языка

Существует множество областей применения Python, но в некоторых он особенно...
admin
13 февраля 2017

Программирование на Python: от новичка до профессионала

Пошаговая инструкция для всех, кто хочет изучить программирование на Python...