Атрибут FILES

Атрибут FILES класса HttpRequest предоставляет доступ к файлам, загруженным пользователем через формы. Он содержит данные в виде словаря, где ключи - это имена полей из формы, а значения - объекты загруженных файлов. FILES доступен только для запросов с методом HttpRequest/attribute/POST/">POST и при условии, что форма имеет атрибут enctype="multipart/form-data". Данные из FILES автоматически обрабатываются Django и предоставляют удобный интерфейс для работы с загруженными файлами.

Синтаксис

pythonrequest.FILES.get('field_name')
request.FILES['field_name']
request.FILES.getlist('field_name')

Пример . Модель для работы с файлами

Для демонстрации работы с атрибутом FILES создадим модель, хранящую информацию о загруженных файлах:

pythonfrom django.db import models

class Document(models.Model):
  title = models.CharField(max_length=100)
  file = models.FileField(upload_to='documents/')
  uploaded_at = models.DateTimeField(auto_now_add=True)

class Image(models.Model):
  name = models.CharField(max_length=100)
  image = models.ImageField(upload_to='images/')
  description = models.TextField(blank=True)

Обработка одиночного файла

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

pythonfrom django.shortcuts import render, redirect
from myapp.models import Document

def upload_document(request):
  if request.method == 'POST':
    uploaded_file = request.FILES.get('document')
    if uploaded_file:
      document = Document.objects.create(
        title=request.POST.get('title', 'Untitled'),
        file=uploaded_file
      )
      return redirect('document_detail', pk=document.pk)
  return render(request, 'upload.html')

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

python"Document uploaded successfully"

Обработка множественных файлов

Для полей, поддерживающих множественную загрузку, используйте метод getlist:

pythonfrom django.shortcuts import render
from myapp.models import Image

def upload_images(request):
  if request.method == 'POST':
    uploaded_files = request.FILES.getlist('images')
    for uploaded_file in uploaded_files:
      Image.objects.create(
        name=uploaded_file.name,
        image=uploaded_file
      )
    return render(request, 'success.html', {
      'count': len(uploaded_files)
    })
  return render(request, 'upload_images.html')

Проверка наличия файлов

Перед обращением к атрибуту FILES рекомендуется проверять наличие файлов:

pythonfrom django.http import HttpResponseBadRequest

def process_files(request):
  if request.method == 'POST':
    if request.FILES:
      for field_name, uploaded_file in request.FILES.items():
        print(f"Field: {field_name}, File: {uploaded_file.name}")
      return render(request, 'files_list.html', {
        'files': request.FILES.items()
      })
    return HttpResponseBadRequest("No files uploaded")
  return render(request, 'upload_form.html')

Проверка размера и типа файла

Атрибут FILES позволяет проверять свойства загружаемых файлов:

pythonfrom django.http import HttpResponse
from django.shortcuts import render

def validate_file(request):
  if request.method == 'POST':
    uploaded_file = request.FILES.get('document')
    if uploaded_file:
      file_size = uploaded_file.size
      file_type = uploaded_file.content_type
      file_name = uploaded_file.name

      if file_size > 1024 * 1024:
        return HttpResponse("File too large. Max 1MB")

      if not file_type.startswith('image/'):
        return HttpResponse("Only images allowed")

      # Process valid file
      return render(request, 'file_info.html', {
        'name': file_name,
        'size': file_size,
        'type': file_type
      })
    return HttpResponse("No file selected")
  return render(request, 'upload.html')

Сохранение файла вручную

При необходимости файл можно сохранить вручную, используя объект из FILES:

pythonimport os
from django.conf import settings
from django.shortcuts import render

def custom_save(request):
  if request.method == 'POST':
    uploaded_file = request.FILES.get('file')
    if uploaded_file:
      file_path = os.path.join(settings.MEDIA_ROOT, uploaded_file.name)
      with open(file_path, 'wb+') as destination:
        for chunk in uploaded_file.chunks():
          destination.write(chunk)
      return render(request, 'file_saved.html', {
        'path': file_path
      })
  return render(request, 'upload.html')

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

  • атрибут GET,
    который содержит параметры запроса из URL
  • атрибут POST,
    который содержит данные формы, отправленные методом POST
  • класс HttpRequest,
    который является основным объектом запроса в Django
  • класс FileResponse,
    который используется для отправки файлов в ответе