feat: add item images, product detail page, and gallery support in catalog
All checks were successful
Build and Push Docker Image / build (push) Successful in 45s
All checks were successful
Build and Push Docker Image / build (push) Successful in 45s
- Added `ItemImage` model with migration for image handling and metadata - Implemented product gallery in `detail.html` with thumbnails for additional images - Updated `Item` model to include `primary_image` property for gallery logic - Enhanced `catalog/index.html` to support item thumbnails - Updated `catalog.css` for responsive gallery and item list styling - Extended catalog views to prefetch images for efficient queries - Added comprehensive tests for catalog and detail views - Configured Django to serve media files in development - Updated admin with inline support for managing `ItemImage` entities
This commit is contained in:
@@ -1,6 +1,32 @@
|
||||
<main class="item-list">
|
||||
<div class="items-grid">
|
||||
{% for item in items %}
|
||||
<h1>item</h1>
|
||||
{% endfor %}
|
||||
<article class="item-card">
|
||||
<a class="item-card-link" href="{% url 'detail' item.category.slug item.slug %}" aria-label="Открыть товар {{ item.name }}">
|
||||
{% with primary_image=item.primary_image %}
|
||||
<div class="item-card-image">
|
||||
{% if primary_image %}
|
||||
<img src="{{ primary_image.image.url }}" alt="{{ primary_image.alt|default:item.name }}">
|
||||
{% else %}
|
||||
<div class="item-card-placeholder">Нет фото</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endwith %}
|
||||
|
||||
</main>
|
||||
<div class="item-card-body">
|
||||
<div class="item-card-category">{{ item.category.name }}</div>
|
||||
<h2 class="item-card-title">{{ item.name }}</h2>
|
||||
<div class="item-card-footer">
|
||||
<span class="item-card-price">{{ item.price }} руб.</span>
|
||||
<span class="item-card-availability {% if item.is_available %}available{% else %}unavailable{% endif %}">
|
||||
{% if item.is_available %}В наличии{% else %}Нет в наличии{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
{% empty %}
|
||||
<p class="item-list-empty">В этой категории пока нет товаров.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
<aside>
|
||||
<section class="categories a-section">
|
||||
<h2>Категории</h2>
|
||||
<a href="/catalog/" class="category {% if selected_category.id == None %}active{% endif %}">Все товары</a>
|
||||
{% for category in categories %}
|
||||
<a href="/catalog/{{ category.slug }}" class="category">{{ category.name }}</a>
|
||||
<a href="/catalog/{{ category.slug }}/" class="category {% if selected_category.id == category.slug %}active{% endif %}">
|
||||
{{ category.name }}
|
||||
</a>
|
||||
{% empty %}
|
||||
<p class="categories-empty">Категории пока не добавлены.</p>
|
||||
{% endfor %}
|
||||
</section>
|
||||
|
||||
@@ -13,26 +18,22 @@
|
||||
<form action="">
|
||||
<section class="a-section cost-section">
|
||||
<h2>Стоимость</h2>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="a-section color-section">
|
||||
<h2>Цвет</h2>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="a-section material-section">
|
||||
<h2>Материал</h2>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="a-section promotions-section">
|
||||
<h2>Акции</h2>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="a-section new-section">
|
||||
<h2>Новинки</h2>
|
||||
</section>
|
||||
</form>
|
||||
</aside>
|
||||
</aside>
|
||||
|
||||
69
templates/catalog/detail.html
Normal file
69
templates/catalog/detail.html
Normal file
@@ -0,0 +1,69 @@
|
||||
{% extends "_layouts/base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}{{ item.name }}{% endblock %}
|
||||
|
||||
{% block add_css %}
|
||||
<link rel="stylesheet" href="{% static "css/catalog.css" %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% include "_fragments/header.html" with active="catalog" %}
|
||||
|
||||
{% url 'detail' item.category.slug item.slug as product_url %}
|
||||
{% include '_fragments/breadcrumbs.html' with url_1='/' text_1='Главная' url_2='/catalog/' text_2='Каталог' url_3='/catalog/'|add:item.category.slug|add:'/' text_3=item.category.name url_4=product_url text_4=item.name %}
|
||||
|
||||
<main class="container product-detail">
|
||||
<section class="product-gallery" aria-label="Изображения товара">
|
||||
<div class="product-gallery__main">
|
||||
{% if primary_image %}
|
||||
<a href="{{ primary_image.image.url }}" data-fancybox="product-gallery">
|
||||
<img src="{{ primary_image.image.url }}" alt="{{ primary_image.alt|default:item.name }}">
|
||||
</a>
|
||||
{% else %}
|
||||
<div class="product-gallery__placeholder">Нет фото</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if images %}
|
||||
<div class="product-gallery__thumbs">
|
||||
{% for image in images %}
|
||||
<a class="product-gallery__thumb{% if forloop.first %} active{% endif %}" href="{{ image.image.url }}" data-fancybox="product-gallery">
|
||||
<img src="{{ image.image.url }}" alt="{{ image.alt|default:item.name }}">
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
<section class="product-summary" aria-label="Информация о товаре">
|
||||
<p class="product-summary__category">{{ item.category.name }}</p>
|
||||
<h1 class="product-summary__title">{{ item.name }}</h1>
|
||||
|
||||
<div class="product-summary__meta">
|
||||
<span class="product-summary__price">{{ item.price }} руб.</span>
|
||||
<span class="product-summary__availability {% if item.is_available %}available{% else %}unavailable{% endif %}">
|
||||
{% if item.is_available %}В наличии{% else %}Нет в наличии{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="product-summary__swatches" aria-hidden="true">
|
||||
<span class="product-summary__swatch product-summary__swatch--dark"></span>
|
||||
<span class="product-summary__swatch product-summary__swatch--graphite"></span>
|
||||
<span class="product-summary__swatch product-summary__swatch--taupe"></span>
|
||||
<span class="product-summary__swatch product-summary__swatch--sand"></span>
|
||||
</div>
|
||||
|
||||
{% if item.description %}
|
||||
<div class="product-summary__description">{{ item.description|linebreaksbr }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="product-summary__actions">
|
||||
<button class="product-summary__button product-summary__button--primary" type="button">В корзину</button>
|
||||
<button class="product-summary__button product-summary__button--secondary" type="button">Купить</button>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
{% include "_fragments/footer.html" %}
|
||||
{% endblock %}
|
||||
@@ -18,10 +18,10 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="container catalog-container">
|
||||
{% include 'catalog/_fragments/side-bar.html' with categories=categories %}
|
||||
{% include 'catalog/_fragments/side-bar.html' with categories=categories selected_category=selected_category %}
|
||||
|
||||
{% include 'catalog/_fragments/item-list.html' with items=items %}
|
||||
</div>
|
||||
|
||||
{% include "_fragments/footer.html" %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user