- Complete guide for using responsive image sizes in templates - Examples for all template types (lists, galleries, modals) - Performance metrics and optimization tips - Size recommendations for each context - Troubleshooting and best practices
13 KiB
Руководство по использованию изображений на фронтенде
Обзор
Система автоматически служит изображения разных размеров в зависимости от контекста:
- Списки товаров: миниатюры (150×150) - быстрая загрузка
- Карточки товаров: средний размер (400×400) - хороший баланс
- Галереи и модальные окна: большой размер (800×800) - высокое качество
- Полноэкранный просмотр: оригинал - максимальное качество
Использованные размеры в шаблонах
1. all_products_list.html (Объединённый список товаров и комплектов)
<!-- Список с миниатюрами -->
<img src="{{ photo.get_thumbnail_url }}" alt="{{ item.name }}" class="img-thumbnail">
Размер на диске: 438B (93% экономия) Использование: Таблица со списком товаров, быстрая загрузка
2. product_list.html (Список только товаров)
<!-- В таблице - миниатюры -->
<img src="{{ photo.get_thumbnail_url }}" alt="{{ product.name }}" class="img-thumbnail">
Размер на диске: 438B (93% экономия) Использование: Табличное отображение товаров
3. productkit_list.html (Список комплектов)
<!-- В таблице - миниатюры -->
<img src="{{ photo.get_thumbnail_url }}" alt="{{ kit.name }}" class="img-thumbnail">
Размер на диске: 438B (93% экономия) Использование: Табличное отображение комплектов
4. product_detail.html (Детали товара с галереей)
Миниатюры в сетке:
<!-- Сетка с thumbnail размерами -->
<img src="{{ photo.get_thumbnail_url }}"
alt="Фото товара"
style="max-width: 100%; max-height: 100%; object-fit: contain;">
Файл: 438B Использование: Маленькие превью для клика
Модальное окно галереи (carousel):
<!-- В модальном окне - большие размеры 800x800 -->
<img src="{{ photo.get_large_url }}"
class="d-block"
alt="Фото товара"
style="max-height: 70vh; max-width: 100%; object-fit: contain;">
Файл: 5.6K Использование: Полноэкранный просмотр, хорошее качество
5. productkit_detail.html (Детали комплекта)
Боковая панель с фото:
<!-- Средний размер для превью -->
<img src="{{ photo.get_medium_url }}"
class="card-img-top"
alt="{{ kit.name }}"
style="height: 120px; object-fit: cover; cursor: pointer;">
Файл: 2.9K Использование: Кликабельные превью в боку
Модальное окно при клике:
<!-- Большой размер в модальном окне -->
<img src="{{ photo.get_large_url }}"
class="img-fluid"
style="max-height: 70vh;">
Файл: 5.6K Использование: Полноэкранный просмотр одного фото
6. category_detail.html (Детали категории)
<!-- Средний размер для отображения -->
<img src="{{ photo.get_medium_url }}"
class="card-img-top"
alt="Фото категории"
style="height: 150px; object-fit: cover;">
Файл: 2.9K Использование: Картинка категории в сетке
Доступные методы
Каждая Photo-модель имеет методы для получения URL разных размеров:
photo = ProductPhoto.objects.first()
# Получить URL миниатюры (150×150)
photo.get_thumbnail_url()
# → /media/products/thumbnails/image_12345.jpg (438B)
# Получить URL среднего размера (400×400)
photo.get_medium_url()
# → /media/products/medium/image_12345.jpg (2.9K)
# Получить URL большого размера (800×800)
photo.get_large_url()
# → /media/products/large/image_12345.jpg (5.6K)
# Получить URL оригинала (без изменений)
photo.get_original_url()
# → /media/products/originals/image_12345.jpg (6.1K)
# Получить все URL за раз
photo.get_all_urls()
# → {
# 'thumbnail': '/media/products/thumbnails/...',
# 'medium': '/media/products/medium/...',
# 'large': '/media/products/large/...',
# 'original': '/media/products/originals/...'
# }
То же самое для ProductKitPhoto и ProductCategoryPhoto.
Рекомендации по использованию
Списки и таблицы
<!-- Миниатюры для быстрой загрузки -->
{% if item.photos.all %}
<img src="{{ item.photos.first.get_thumbnail_url }}"
alt="{{ item.name }}"
style="max-width: 50px; max-height: 50px;">
{% endif %}
Почему: Список может содержать 50+ товаров, миниатюры загружаются мгновенно
Карточки товаров
<!-- Средний размер для карточек -->
<div class="product-card">
<img src="{{ product.photos.first.get_medium_url }}"
alt="{{ product.name }}">
</div>
Почему: Карточка требует хорошего качества, но не нужна полная 800×800
Модальные окна и галереи
<!-- Большой размер для полного просмотра -->
<div class="modal-body">
<img src="{{ photo.get_large_url }}"
alt="{{ product.name }}"
style="max-width: 100%; max-height: 70vh;">
</div>
Почему: Пользователь просматривает один товар, качество важнее
Ссылка на оригинал
<!-- Для скачивания оригинала -->
<a href="{{ photo.get_original_url }}"
download>
Скачать оригинал
</a>
Почему: Для печати или отправки по почте нужно максимальное качество
Производительность
Пример загрузки страницы:
Список товаров (20 товаров):
- 20 × 438B = 8.76 КБ
- Время загрузки: ~100мс на медленном 3G
VS если бы были оригиналы:
- 20 × 6.1K = 122 КБ
- Время загрузки: ~1.2сек на медленном 3G
Экономия: 93% трафика, 12× быстрее ⚡
Адаптивный дизайн
Система изображений работает на всех устройствах:
<!-- Адаптивное отображение -->
<img src="{{ photo.get_thumbnail_url }}"
alt="{{ product.name }}"
class="img-fluid"
style="max-width: 100%;">
- На мобильных: 50px → выглядит хорошо
- На планшетах: 50px → увеличение не требуется
- На десктопе: 50px → оптимально
Для больших экранов используются большие размеры (800×800) в модальном окне.
Примеры в JavaScript
Если нужно работать с изображениями через JavaScript:
// Получить URL через атрибут data
const largeImageUrl = document.querySelector('[data-large-url]').dataset.largeUrl;
// Или из HTML через обычный селектор
const img = document.querySelector('.product-image');
const src = img.src; // /media/products/medium/image_12345.jpg
Загрузка изображений
Через админку:
- Откройте товар/комплект/категорию в админке
- В секции "Фото товара" загрузите изображение
- Система автоматически создаст все 4 размера!
- Фото появится во всех шаблонах с правильным размером
Через API (если нужно):
from products.models import ProductPhoto
from products.utils.image_processor import ImageProcessor
photo = ProductPhoto(product=product)
photo.image = request.FILES['image']
photo.save() # Все размеры создадутся автоматически
Кэширование и оптимизация
Текущая реализация:
- Каждый размер сохраняется на диск (быстро)
- URL вычисляется динамически (не нужна дополнительная БД)
Будущие оптимизации (опционально):
- Redis кэширование URL
- WebP формат для современных браузеров
- Ленивая загрузка изображений (lazy loading)
- CDN интеграция
Поиск и устранение проблем
Изображение не загружается
- Проверьте консоль браузера (F12 → Network)
- Правильный ли URL? (должен быть
/media/products/...) - Загруженное ли изображение в админке?
Размер слишком мал/велик
- Используйте правильный метод:
get_thumbnail_url()→ для списковget_medium_url()→ для карточекget_large_url()→ для галерейget_original_url()→ для оригинала
Качество плохое
- Используйте
get_large_url()илиget_original_url()вместоget_thumbnail_url()
Примеры полных шаблонов
Пример 1: Сетка товаров (Bootstrap)
<div class="row row-cols-1 row-cols-md-3 g-4">
{% for product in products %}
<div class="col">
<div class="card h-100">
<!-- Миниатюра - быстро загружается -->
{% if product.photos.first %}
<img src="{{ product.photos.first.get_thumbnail_url }}"
class="card-img-top"
alt="{{ product.name }}"
loading="lazy">
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
<p class="card-text">{{ product.description|truncatewords:20 }}</p>
<a href="{% url 'products:product-detail' product.pk %}"
class="btn btn-primary">
Открыть →
</a>
</div>
</div>
</div>
{% endfor %}
</div>
Пример 2: Галерея с модальным окном
<div class="row g-2">
{% for photo in product.photos.all %}
<div class="col-md-3">
<!-- Кликабельная миниатюра -->
<div class="card"
role="button"
data-bs-toggle="modal"
data-bs-target="#photoModal{{ photo.pk }}"
style="cursor: pointer;">
<img src="{{ photo.get_thumbnail_url }}"
class="card-img-top"
alt="{{ product.name }}"
style="height: 150px; object-fit: cover;">
</div>
</div>
<!-- Модальное окно с большим размером -->
<div class="modal fade" id="photoModal{{ photo.pk }}">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-body">
<img src="{{ photo.get_large_url }}"
class="img-fluid"
alt="{{ product.name }}">
</div>
</div>
</div>
</div>
{% endfor %}
</div>
Итоги
✅ Автоматическое масштабирование - правильный размер в правильном месте ✅ Экономия трафика - 90% для миниатюр ✅ Быстрая загрузка - миниатюры 438B ✅ Высокое качество - большие размеры 800×800 для просмотра ✅ Простой API - всего 4 метода в шаблонах ✅ Полная автоматизация - создание размеров при загрузке
Система готова к использованию! 🎉