На Django сайтах содержимое страниц обычно хранится в базе данных, которую описывает модель. Однако, если мы работаем с изображениями, всё немного сложнее. Обычно мы не храним их в базе данных, а складываем на файловую систему (или иное хранилище), а в базе хранится лишь идентификатор (путь до файла).
Для этого в Django есть django.db.models.ImageField
. Добавив это поле,
мы определяем, что в нашей модели есть поле с изображением, а в админке
появляется и возможность загрузить его. Другое дело,
не понятно куда оно будет загружено, как его вывести на сайте.
Что ж, приступим! Начнём файла настроек settings.py
:
MEDIA_ROOT = f'{BASE_DIR}/media'
MEDIA_URL = '/media/'
Здесь мы указываем, в какой директории будут храниться сами файлы (MEDIA_ROOT
),
а также по какому префиксу url будут искаться при запросе от клиента (MEDIA_URL
).
Также помним, что BASE_DIR
указывает на корень проекта. Так что при этих
настройках директория для медиа-файлов будет в той же папке, что
и директории наших приложений. Если хотите, чтобы файлы хранились вне
папки с кодом Django-проекта, то MEDIA_ROOT = f'{BASE_DIR}/../media'
- будет
как раз на уровень выше.
Далее добавим связь MEDIA_URL
к MEDIA_ROOT
, чтобы данный префикс вёл на файлы.
Делаем это в urls.py
:
from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
...
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Как можно заметить, включаем эти url-ы только в случае отладки (во время разработки) так как django-сервер для разработки не предназначен для боевых серверов.
На боевых же серверах у вас Django, скорее всего, будет стоять за высокопроизводительным сервером, например, nginx. Поэтому пусть nginx и займётся работой со статическими файлами. Для nginx нужно будет в конфигурационном файле указать настройку location:
location ~* /media/.*?\.(html|txt|jpg|jpeg|gif|png|pdf|ico|css|bmp|js|swf|otf|woff|ttf|gz|svg|ogg)$ {
root /путь/до/папки/media;
expires 30m;
add_header Cache-Control public;
}
Далее посмотрим на модель данных:
from django.db import models
class Product(models.Model):
img = models.ImageField(upload_to='product', null=True, blank=True, verbose_name='Изображение')
...
Советую указать параметр upload_to
- будет создана поддиректория в MEDIA_ROOT
,
в которой будут храниться изображения для этой модели. Это более удобный
способ хранения файлов, чем хранить всё в одной "куче".
Само же изображение в templates
выводится просто:
<img src="{{ object.img.url }}" />