Как загрузить файлы с 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
Вернуться на верх