# Примеры использования системы хранения изображений ## Содержание 1. [Примеры в шаблонах](#примеры-в-шаблонах) 2. [Примеры в представлениях](#примеры-в-представлениях) 3. [Примеры в моделях](#примеры-в-моделях) 4. [Примеры в админке](#примеры-в-админке) 5. [Примеры JSON API](#примеры-json-api) 6. [Продвинутые примеры](#продвинутые-примеры) --- ## Примеры в шаблонах ### Пример 1: Простой список товаров ```django {% extends 'base.html' %} {% block content %}
{% for product in products %}
{% if product.photos.first %} {{ product.name }} {% else %}
Нет фото
{% endif %}

{{ product.name }}

{{ product.sale_price }} ₽

{% endfor %}
{% endblock %} ``` ### Пример 2: Карточка товара с галереей ```django {% extends 'base.html' %} {% block content %}

{{ product.name }}

{{ product.description }}

{{ product.sale_price }} ₽

{% endblock %} ``` ### Пример 3: Каталог комплектов с категориями ```django {% extends 'base.html' %} {% block content %}
{% for category in categories %}

{{ category.name }}

{% for kit in category.kits.all %}
{% if kit.photos.first %}
{{ kit.name }}
{% endif %}

{{ kit.name }}

от {{ kit.get_sale_price }} ₽

Подробнее
{% endfor %}
{% endfor %}
{% endblock %} ``` ### Пример 4: Слайдер (carousel) ```django {% extends 'base.html' %} {% block content %}
{% for photo in featured_photos %}

{{ photo.product.name }}

{{ photo.product.description|truncatewords:20 }}

{% endfor %}
{% endblock %} ``` --- ## Примеры в представлениях ### Пример 1: Список товаров с пагинацией ```python from django.shortcuts import render from django.views.generic import ListView from products.models import Product class ProductListView(ListView): model = Product template_name = 'products/list.html' context_object_name = 'products' paginate_by = 12 def get_queryset(self): return Product.active.prefetch_related('photos') def products_list(request): products = Product.active.prefetch_related('photos').all() context = { 'products': products, } return render(request, 'products/list.html', context) ``` ### Пример 2: Детальный вид товара ```python from django.shortcuts import render, get_object_or_404 from products.models import Product def product_detail(request, pk): product = get_object_or_404(Product, pk=pk) photos = product.photos.all().order_by('order') # Получить все URL для шаблона main_photo = photos.first() all_photo_urls = [] if main_photo: all_photo_urls = [{ 'thumbnail': photo.get_thumbnail_url(), 'medium': photo.get_medium_url(), 'large': photo.get_large_url(), 'original': photo.get_original_url(), } for photo in photos] context = { 'product': product, 'photos': photos, 'photo_urls': all_photo_urls, 'main_photo': main_photo, } return render(request, 'products/detail.html', context) ``` ### Пример 3: API endpoint с изображениями ```python from django.http import JsonResponse from products.models import Product def product_api(request, pk): product = Product.objects.get(pk=pk) photo = product.photos.first() data = { 'id': product.id, 'name': product.name, 'price': float(product.sale_price), 'images': { 'thumbnail': photo.get_thumbnail_url() if photo else None, 'medium': photo.get_medium_url() if photo else None, 'large': photo.get_large_url() if photo else None, 'original': photo.get_original_url() if photo else None, } } return JsonResponse(data) ``` ### Пример 4: Экспорт в CSV с ссылками на изображения ```python import csv from django.http import HttpResponse from products.models import Product def export_products_csv(request): response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="products.csv"' writer = csv.writer(response) writer.writerow(['ID', 'Название', 'Цена', 'Фото (thumbnail)', 'Фото (original)']) for product in Product.active.prefetch_related('photos'): photo = product.photos.first() writer.writerow([ product.id, product.name, product.sale_price, photo.get_thumbnail_url() if photo else '', photo.get_original_url() if photo else '', ]) return response ``` --- ## Примеры в моделях ### Пример 1: Добавить метод для получения лучшего фото ```python from products.models import Product class ProductWithBestPhoto(Product): """Добавить метод для получения лучшего фото по рейтингу""" def get_best_photo(self): """Получить фото с наименьшим order (основное)""" return self.photos.first() def get_photo_urls(self): """Получить словарь всех URL основного фото""" photo = self.get_best_photo() if not photo: return { 'thumbnail': '', 'medium': '', 'large': '', 'original': '', } return { 'thumbnail': photo.get_thumbnail_url(), 'medium': photo.get_medium_url(), 'large': photo.get_large_url(), 'original': photo.get_original_url(), } ``` ### Пример 2: Сигнал для логирования при загрузке фото ```python from django.db.models.signals import post_save from django.dispatch import receiver from products.models import ProductPhoto import logging logger = logging.getLogger(__name__) @receiver(post_save, sender=ProductPhoto) def log_photo_upload(sender, instance, created, **kwargs): if created: logger.info(f"Новое фото для товара '{instance.product.name}': {instance.image.name}") else: logger.info(f"Фото для товара '{instance.product.name}' обновлено: {instance.image.name}") ``` --- ## Примеры в админке ### Пример: Кастомная админка с дополнительными фильтрами ```python from django.contrib import admin from products.models import Product, ProductPhoto class ProductPhotoInline(admin.TabularInline): model = ProductPhoto extra = 0 fields = ('image', 'order') readonly_fields = ('image_preview',) class ProductAdminCustom(admin.ModelAdmin): list_display = ('name', 'photo_count', 'has_photos', 'created_at') inlines = [ProductPhotoInline] def photo_count(self, obj): """Количество фото""" return obj.photos.count() photo_count.short_description = 'Фото' def has_photos(self, obj): """Есть ли фото""" return obj.photos.exists() has_photos.boolean = True has_photos.short_description = 'Есть фото' ``` --- ## Примеры JSON API ### Пример: REST API с сериализаторами (DRF) ```python from rest_framework import serializers from products.models import Product, ProductPhoto class ProductPhotoSerializer(serializers.ModelSerializer): thumbnail_url = serializers.SerializerMethodField() medium_url = serializers.SerializerMethodField() large_url = serializers.SerializerMethodField() original_url = serializers.SerializerMethodField() class Meta: model = ProductPhoto fields = ['id', 'thumbnail_url', 'medium_url', 'large_url', 'original_url'] def get_thumbnail_url(self, obj): return obj.get_thumbnail_url() def get_medium_url(self, obj): return obj.get_medium_url() def get_large_url(self, obj): return obj.get_large_url() def get_original_url(self, obj): return obj.get_original_url() class ProductSerializer(serializers.ModelSerializer): photos = ProductPhotoSerializer(many=True) class Meta: model = Product fields = ['id', 'name', 'price', 'photos'] ``` ### Пример JSON ответ: ```json { "id": 1, "name": "Роза красная Freedom", "price": "150.00", "photos": [ { "id": 1, "thumbnail_url": "/media/products/thumbnails/rose_12345.jpg", "medium_url": "/media/products/medium/rose_12345.jpg", "large_url": "/media/products/large/rose_12345.jpg", "original_url": "/media/products/originals/rose_12345.jpg" } ] } ``` --- ## Продвинутые примеры ### Пример 1: Оптимизированный запрос для перечисления ```python from django.db.models import Prefetch from products.models import Product, ProductPhoto def get_optimized_products(queryset=None): """ Получить товары с оптимизированными запросами к фото """ if queryset is None: queryset = Product.active # Prefetch только первое фото для каждого товара photo_prefetch = Prefetch( 'photos', ProductPhoto.objects.order_by('order')[:1] ) return queryset.prefetch_related(photo_prefetch) # Использование products = get_optimized_products() for product in products: photo = product.photos.first() print(f"{product.name}: {photo.get_medium_url()}") ``` ### Пример 2: Кэширование URL в Redis ```python from django.core.cache import cache from products.models import ProductPhoto def get_photo_urls_cached(photo_id, timeout=3600): """ Получить все URL фото из кэша или создать новые """ cache_key = f'photo_urls_{photo_id}' urls = cache.get(cache_key) if urls is None: photo = ProductPhoto.objects.get(id=photo_id) urls = { 'thumbnail': photo.get_thumbnail_url(), 'medium': photo.get_medium_url(), 'large': photo.get_large_url(), 'original': photo.get_original_url(), } cache.set(cache_key, urls, timeout) return urls # Использование urls = get_photo_urls_cached(photo_id=1) ``` ### Пример 3: Генерация миниатюр для социальных сетей ```python from products.models import Product from products.utils.image_service import ImageService def get_social_media_image(product): """ Получить оптимальное изображение для социальных сетей """ photo = product.photos.first() if not photo: return None social_images = { 'og_image': photo.get_large_url(), # Facebook, VK 'twitter_image': photo.get_medium_url(), 'pinterest': photo.get_original_url(), 'instagram_thumbnail': photo.get_thumbnail_url(), } return social_images # Использование в шаблоне {% with social_images=get_social_media_image %} {% endwith %} ``` ### Пример 4: Batch обработка и переформатирование ```python from django.core.management.base import BaseCommand from products.models import Product class Command(BaseCommand): help = 'Переобработать все изображения' def handle(self, *args, **options): for product in Product.objects.prefetch_related('photos'): for photo in product.photos.all(): # Пересохранить - это вызовет переобработку photo.save() self.stdout.write(f"✓ {product.name}") ``` --- ## Чек-лист для разработчика Когда добавляете изображения в новую модель: - [ ] Наследуется ли модель от `Photo*`? - [ ] Есть ли методы `get_*_url()`? - [ ] Переопределены ли `save()` и `delete()`? - [ ] Добавлена ли в админку? - [ ] Добавлен ли `prefetch_related` в queryset? - [ ] Проверены ли все размеры в шаблонах? --- ## Производительность Типичные цифры на проекте с 1000 товарами: | Операция | Время | |----------|-------| | Загрузка товара + первое фото | 5мс | | Получение URL миниатюры | 0.1мс | | Вся галерея (10 фото) | 50мс | | Экспорт в CSV (1000 товаров) | 2сек | --- Больше примеров и кейсов см. в основной документации: `IMAGE_STORAGE_STRATEGY.md`