Everything you wanted to know
about the Django framework

Как загрузить файлы с Django

В этом руководстве вы узнаете о принципах загрузки файлов Django и о том, как обрабатывать загрузку файлов с использованием форм моделей. В конце этого поста вы найдете исходный код примеров, которые я использовал, чтобы вы могли попробовать и изучить.

Также не забудьте ознакомиться с документацией Django по загрузке файлов.

Основы загрузки файлов с Django

Когда файлы передаются на сервер, данные файла в конечном итоге помещаются в request.FILES.

Для формы HTML обязательно должен быть правильно установлен атрибут enctype="multipart/form-data". В противном случае request.FILES будет пустым.

Форма должна быть отправлена методом POST.

У Django есть подходящие поля модели для обработки загруженных файлов: FileField и ImageField.

Файлы, загруженные в FileField или ImageField, хранятся не в базе данных, а в файловой системе.

FileField и ImageField создаются как строковое поле в базе данных (обычно VARCHAR), содержащее ссылку на фактический файл.

Если вы удалите экземпляр модели, содержащий FileField или ImageField, Django не удалит физический файл, а только ссылку на файл.

Аргумент request.FILES является словарным объектом. Каждый ключ в request.FILES - это имя из <input type="file" name="" />.

Каждое значение в request.FILES является экземпляром UploadedFile.

Вам нужно будет установить MEDIA_URL и MEDIA_ROOT в файле settings.py вашего проекта.

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

На сервере разработки вы можете обслуживать загруженные пользователем файлы (мультимедиа), используя представление django.contrib.staticfiles.views.serve().

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # Project url patterns...
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Чтобы получить доступ к MEDIA_URL в шаблоне, вы должны добавить django.template.context_processors.media к вашим context_processors в конфигурации TEMPLATES.

Простая загрузка файла

Ниже приведен минимальный пример загрузки файла с использованием FileSystemStorage. Используйте это просто, чтобы узнать о ходе процесса.

simple_upload.html

{% extends 'base.html' %}

{% load static %}

{% block content %}
  <form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="myfile">
    <button type="submit">Upload</button>
  </form>

  {% if uploaded_file_url %}
    <p>File uploaded at: <a href="{{ uploaded_file_url }}">{{ uploaded_file_url }}</a></p>
  {% endif %}

  <p><a href="{% url 'home' %}">Return to home</a></p>
{% endblock %}

views.py

from django.shortcuts import render
from django.conf import settings
from django.core.files.storage import FileSystemStorage

def simple_upload(request):
    if request.method == 'POST' and request.FILES['myfile']:
        myfile = request.FILES['myfile']
        fs = FileSystemStorage()
        filename = fs.save(myfile.name, myfile)
        uploaded_file_url = fs.url(filename)
        return render(request, 'core/simple_upload.html', {
            'uploaded_file_url': uploaded_file_url
        })
    return render(request, 'core/simple_upload.html')

Загрузка файла с модельными формами

Это более удобный способ. Формы моделей выполняют валидацию, автоматически строят абсолютный путь для загрузки, обрабатывают конфликты имен файлов и другие распространенные задачи.

models.py

from django.db import models

class Document(models.Model):
    description = models.CharField(max_length=255, blank=True)
    document = models.FileField(upload_to='documents/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

forms.py

from django import forms
from uploads.core.models import Document

class DocumentForm(forms.ModelForm):
    class Meta:
        model = Document
        fields = ('description', 'document', )

views.py

def model_form_upload(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('home')
    else:
        form = DocumentForm()
    return render(request, 'core/model_form_upload.html', {
        'form': form
    })

model_form_upload.html

{% extends 'base.html' %}

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

  <p><a href="{% url 'home' %}">Return to home</a></p>
{% endblock %}

О параметре FileField upload_to

Смотрите пример ниже:

document = models.FileField(upload_to='documents/')

Обратите внимание на параметр upload_to. Файлы будут автоматически загружены в MEDIA_ROOT/documents/.

Также возможно сделать что-то вроде:

document = models.FileField(upload_to='documents/%Y/%m/%d/')

Загруженный сегодня файл будет загружен в MEDIA_ROOT/documents/2019/08/01/.

upload_to также может быть вызываемым параметром, который возвращает строку. Этот вызываемый параметр принимает два параметра, экземпляр (instance) и имя файла (filename).

def user_directory_path(instance, filename):
    # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
    return 'user_{0}/{1}'.format(instance.user.id, filename)

class MyModel(models.Model):
    upload = models.FileField(upload_to=user_directory_path)

Скачать примеры

Код, используемый в этом посте, доступен на Github.

git clone https://github.com/sibtc/simple-file-upload.git
pip install django
python manage.py migrate
python manage.py runserver

Перевод статьи https://simpleisbetterthancomplex.com/tutorial/2016/08/01/how-to-upload-files-with-django.html

Поделитесь с другими:

Представления-классы
(Class-Based Views)

Детальное описание и структура классов Django.

Выпуск Django 3.0

Команда Django рада объявить о выпуске Django 3.0: движение к тому, чтобы сделать Django полностью асинхронным, предоставляя поддержку для работы в качестве приложения ASGI, теперь официально поддерживает MariaDB 10.1 и выше, а также много других новых функций и возможностей.

Выпущены релизы безопасности Django: 2.2.8 и 2.1.15

В соответствии с политикой безопасности, команда Django выпускает Django 2.2.8 и Django 2.1.15. Этот выпуск решает проблему безопасности, подробно описанную ниже. Мы призываем всех пользователей Django обновиться как можно скорее.

Путь от request до response в Джанго

Веб-приложение или веб-сайт вращаются вокруг цикла запрос-ответ, и приложения Django не являются исключением. Но это не просто двухэтапный процесс. Наши приложения Django должны пройти различные стадии, чтобы вернуть конечному пользователю результат. Чтобы лучше понять структуру Django, мы должны понимать, как инициируются запросы и как конечный результат передается конечному пользователю. В статье объясняются различные этапы запросов и используемое там программное обеспечение или код.

Выпущен релиз-кандидат Django 3.0

Кандидат 1 релиза Django 3.0 - это последняя возможность для вас испытать множество новых функций перед выпуском Django 3.0.

Django DetailView - основы использования

Django позволяет создавать приложения очень легко. Если приложение должно быть выпущено быстро и является относительно общим, то эта среда Python идеально подходит для этого. В течение нескольких лет я профессионально работал в этой среде и часто рылся внутри, поэтому знаю почти всё, и сегодня я представлю вам все, что нужно знать, чтобы эффективно использовать универсальный DetailView в Django.

Выпущены исправления Django: 2.2.7, 2.1.14 и 1.11.26

Сегодня команда разработчиков Django выпустила версии 2.2.7, 2.1.14 и 1.11.26 с исправлениями ошибок. Пакет и контрольные суммы доступны на странице загрузок, а также из индекса пакетов Python. Идентификатор ключа PGP, использованный в этом выпуске: Mariusz Felisiak: 2EF56372BA48CD1B.

Как заставить request.is_ajax() работать с JS fetch()

Объект запроса Django request имеет изящный небольшой метод is_ajax(). Он позволяет определить, поступил ли запрос от JS-фреймворка (он же ajax старой школы). Хотя он отлично работает с некоторыми библиотеками JS, включая почтенный jQuery, он не будет работать с современным встроенным в JS fetch().

Практика программирования на Python 3, лекция №5

Лекции о Python 3 от Тимофея Хирьянова при поддержке Московского физико-технического института. Лекция №5.

Практика программирования на Python 3, лекция №4

Лекции о Python 3 от Тимофея Хирьянова при поддержке Московского физико-технического института. Лекция №4.

Практика программирования на Python 3, лекция №3

Лекции о Python 3 от Тимофея Хирьянова при поддержке Московского физико-технического института. Лекция №3.