Подготовка проекта
Для начала создайте каталог, в котором будут находиться проект и виртуальная среда (она нужна, чтобы отделять проектные зависимости от операционной системы).
Теперь выполните команду cd
на этот каталог и сформируйте виртуальную среду:
mkdir filesDjango
cd filesDjango
python3.8 -m venv env
Активируйте ее и туда же установите Django:
source env/bin/activate
pip install Django
Создайте новый проект Django и назовите его file uploads
:
django-admin startproject fileuploads
В каталоге данного проекта создайте приложение с именем files
. Приложения в Django используются для разделения различных компонентов и необходимы для масштабирования самих приложений. Они также являются перемещаемыми элементами и их можно перетащить в другой проект Django, не ломая код.
django-admin startapp files
Добавьте файлы приложения к списку установленного софта в файле settings.py
:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'files',
]
Django сохраняет файлы локально с помощью параметров MEDIA_ROOT
и MEDIA_URL
.
Определим эти константы в файле settings.py.
:
import os
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_ROOT
будет использоваться для управления сохраненными данными, а MEDIA_URL
— как url данных, которые требуется предоставить.
Загрузка данных
Самый простой вариант — загружать файлы с помощью FileFields
. Начните с создания простой модели в файле models.py
, которая будет содержать три поля: имя, электронную почту и файл для загрузки.
from django.db import models
# Создайте модели здесь.
class Resume(models.Model):
email = models.EmailField()
name = models.CharField(max_length= 255, blank=False, null=False)
file = models.FileField(upload_to= 'files/',null=True)
def __repr__(self):
return 'Resume(%s, %s)' % (self.name, self.file)
def __str__ (self):
return self.name
Параметр upload_to
указывает, куда будут перемещены файлы.
Запуск миграций
Миграции создадут актуальные таблицы в базе данных.
python3.8 manage.py migrate
Формы
Django имеет встроенный класс ModelForm
, позволяющий легко создавать формы из модельных полей. Создайте новый файл forms.py
и добавьте код:
from django import forms
from .models import Resume
class ResumeForm(forms.ModelForm):
class Meta:
model = Resume
fields = ['email','name','file']
Определив форму, вы получите данные из нее с помощью request.FILES
, используя запрос POST
в представлении. Чтобы получить данные, содержащиеся в форме, откройте файл view.py
и напишите следующий код:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .forms import ResumeForm
# Создайте здесь представления.
def upload_resume(request):
if request.method == 'POST':
form = ResumeForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect("/")
else:
form = ResumeForm
return render(request, 'files/resume.html', {'form':form})
В вышеизложенном коде проверьте, чтобы метод запроса был POST
, затем получите данные из формы, проверьте их и сохраните в базе данных. Если метод запроса — GET
, то отобразите форму в шаблоне.
Мы еще не создали шаблон upload.html
(Django автоматически найдет его в соответствующем каталоге), с помощью которого будет отображена форма, так что давайте приступим. Создайте файлы, как показано ниже:
templates/
files/
-upload.html
Для отправки формы в шаблон ей необходим атрибут enctype="multipart/form-data"
, иначе request.FILES
вернется пустым:
{% block content %}
<form method = "post", enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit"> Submit</button>
</form>
{% endblock %}
Тег csrf_token
защитит форму от вредоносных данных, а form.as_p
отобразит поля в виде параграфов.
Регистрация путей URL
Сперва создайте файл urls.py
, чтобы зарегистрировать URL для отображения формы, а затем — urls.py
. Добавляем код:
from django.urls import path
from .views import upload_resume
urlpatterns = [
path('upload_resume/',upload_resume, name = "files" )
]
Следующий шаг — регистрация файлов URL в корне url.py
:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('files.urls'))
]
Теперь, если вы запустите сервер и перейдете по адресу http://127.0.0.1:8000/upload_resume/, вы увидите формы, как изображено ниже:
Django Admin
Django Admin — мощный интерфейс, который позволяет разработчикам добавлять данные в приложении. Зарегистрируем модель Resume
в файле admin.py
:
from django.contrib import admin
from .models import Resume
# Зарегистрируйте вашу модель здесь.
admin.site.register(Resume)
Создание суперпользователя
Суперпользователь позволяет выполнять действия администратора:
python3.8 manage.py createsuperuser
Username (leave blank to use 'earthtoast'):
Email address:
Password:
Password (again):
Superuser created successfully.
Когда вы перейдете по адресу http://127.0.0.1:8000/admin/ и войдете в систему под именем созданного суперпользователя, вы сможете просмотреть представленные данные.
Загрузка изображений в Django
Мы научились загружать файлы с помощью FileField
, но как быть с изображениями? Чтобы загружать картинки, необходимо использовать ImageField
. Переходим в модели и добавляем ImageField
, как показано ниже:
class Image(models.Model):
title = models.CharField(max_length= 255, blank=False, null=False)
image = models.ImageField(upload_to='images/', null=True, max_length=255)
def __repr__(self):
return 'Image(%s, %s)' % (self.title, self.image)
def __str__ (self):
return self.title
Для поля imageField
, которое определено выше, необходима библиотека pillow, поэтому установите ее с помощью pip
:
pip install Pillow
Примените миграции, чтобы повлиять на изменения в моделях:
python3.8 manage.py makemigrations files
Migrations for 'files':
files/migrations/0002_image.py
- Create model Image
Запустите команду migrate
:
python3.8 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, files, sessions
Running migrations:
Applying files.0002_image... OK
Далее создайте форму по примеру Resume
:
from django import forms
from .models import Resume,Image
class ResumeForm(forms.ModelForm):
class Meta:
model = Resume
fields = ['email','name','file']
class ImageForm(forms.ModelForm):
class Meta:
model = Image
fields = ['title','image']
Для отображения изображения в форме необходимо представление. В файл views.py
добавьте код:
def upload_images(request):
if request.method == 'POST':
form = ImageForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect("/")
else:
form = ImageForm
return render(request, 'files/images.html', {'form':form})
Создайте файл image.html
в папке templates
и пропишите в нем следующее:
{% block content %}
<form method = "post", enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit"> Submit</button>
</form>
Теперь подключите представление upload_image
к URL, открывайте urls.py
и прописывайте:
from django.urls import path
from .views import upload_resume,upload_images
urlpatterns = [
path('upload_resume/',upload_resume, name = "files" ),
path('upload_images/',upload_images, name = "images" ),
]
Форму загрузки изображения можно найти по адресу http://127.0.0.1:8000/upload_images/.
Предоставление файлов
Первым делом добавьте django.template.context_processors.media
в опцию context_processors
в TEMPLATES
в файле settings.py
. Это позволит использовать {{ MEDIA_URL }}
в шаблоне:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.media',
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Далее обновите представление, чтобы выбрать изображения из базы данных:
from django.shortcuts import render
from .models import Image
def upload_images(request):
if request.method == 'GET':
images = Image.objects.order_by('title')
return render(request, "files/images.html", {"images": images })
Обновите шаблон image.html
для отображения картинок:
{% for image in images %}
<div>
{{ image.title }}
</div>
<div>
<img src="{{ image.image.url }}" >
</div>
{% endfor %}
Вы можете предоставлять загруженные файлы из медиамаршрута в процессе работы, используя представление django.views.static.serve()
.
Добавьте следующий путь в корень URL-файла:
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('files.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Теперь при переходе по адресу http://127.0.0.1:8000/upload_images/ ваши изображения будут выводиться на экран.
Заключение
В этом гайде затрагиваются все аспекты работы с файлами и медиа в Django. Библиотека Pillow также предоставляет множество функций для открытия, редактирования и сохранения большого количества форматов файлов изображений.
Читайте также:
- Создание проекта Django для регистрации и входа/выхода из системы
- Django-приложение для ведения личного дневника
- Middleware Django: пользовательское ПО промежуточного слоя
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Esther Vaati: How to Upload Files and Images in Your Django Application