Поле ImageField

Поле ImageField применяется в формах Django для обработки загрузки изображений. Оно расширяет функциональность FileField, добавляя дополнительную валидацию, которая проверяет, что загруженный файл является корректным изображением. При использовании этого поля в форме необходимо также добавить атрибут enctype="multipart/form-data" в тег HTML-формы для корректной передачи файлов на сервер. Поле принимает загруженный файл, проверяет его расширение и MIME-тип, а также предоставляет доступ к дополнительным атрибутам изображения, таким как размер и содержимое.

Синтаксис

pythonfrom django import forms

class MyForm(forms.Form):
  image = forms.ImageField(
    label="Image",
    required=False,
    help_text="Upload an image file"
  )

Пример

Рассмотрим простой пример формы с полем для загрузки изображения:

pythonfrom django import forms
from django.core.validators import FileExtensionValidator

class AvatarForm(forms.Form):
  avatar = forms.ImageField(
    label="Avatar",
    required=True,
    help_text="Upload your avatar image",
    validators=[
      FileExtensionValidator(
        allowed_extensions=['jpg', 'jpeg', 'png']
      )
    ]
  )
  
  description = forms.CharField(
    max_length=200,
    required=False,
    label="Description"
  )

Результат вывода формы в шаблоне:

python<form method="post" enctype="multipart/form-data">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Upload</button>
</form>

Пример

Обработка загруженного изображения в представлении:

pythonfrom django.shortcuts import render
from django.http import HttpResponse
from .forms import AvatarForm
from PIL import Image

def upload_avatar(request):
  if request.method == 'POST':
    form = AvatarForm(request.POST, request.FILES)
    if form.is_valid():
      avatar = form.cleaned_data['avatar']
      # Доступ к атрибутам файла
      res = f"File name: {avatar.name}, Size: {avatar.size} bytes"
      # Чтение изображения с помощью PIL
      img = Image.open(avatar)
      res += f", Dimensions: {img.size}"
      return HttpResponse(res)
  else:
    form = AvatarForm()
  return render(request, 'upload.html', {'form': form})

Результат выполнения кода при загрузке изображения:

python"File name: avatar.jpg, Size: 24567 bytes, Dimensions: (800, 600)"

Пример

Использование ImageField в модели и форме на основе модели:

pythonfrom django.db import models
from django import forms

class Profile(models.Model):
  user = models.CharField(max_length=100)
  photo = models.ImageField(upload_to='profiles/')
  created_at = models.DateTimeField(auto_now_add=True)
  
  def __str__(self):
    return self.user

class ProfileForm(forms.ModelForm):
  class Meta:
    model = Profile
    fields = ['user', 'photo']
    
  def clean_photo(self):
    photo = self.cleaned_data.get('photo')
    if photo:
      if photo.size > 5 * 1024 * 1024:
        raise forms.ValidationError(
          "Image file too large (> 5MB)"
        )
    return photo

Результат валидации при загрузке файла размером 10 МБ:

python"Image file too large (> 5MB)"

Смотрите также

  • поле FileField,
    которое используется для загрузки любых файлов
  • класс ModelForm,
    который автоматически создает форму на основе модели
  • метод save,
    который сохраняет данные формы в базу данных
  • виджет ClearableFileInput,
    который отображает поле с возможностью очистки