64. Similar products
Next, we will edit the view_product.html
file to add a "Similar Products" section below the product details. A product will be considered similar if it shares the same category and type but is not the current product.
The similares
section in the view_product.html
file has been updated accordingly to display these similar products dynamically.
{% extends 'base.html' %}
{% load static %}
{% block body %}
<main class="principal principal--padding-b principal--gap">
<section class="s-produto">
<div class="s-produto__carrossel">
<div class="s-produto__carrossel-itens">
<div class="s-produto__carrossel-img">
<img
src="{{ product.image.url }}"
alt="Imagem Carrossel 1"
/>
</div>
<div class="s-produto__carrossel-img" style="overflow: hidden;"> <!--Avoids the size itself of the image of getting big-->
<img
src="{{ product.image.url }}"
alt="Imagem Carrossel 2"
style="transform: scale(1.6);"
/>
</div>
</div>
<div class="s-produto__carrossel-botoes">
<div
class="s-produto__carrossel-botao s-produto__carrossel-botao--selecionado"
></div>
<div class="s-produto__carrossel-botao"></div>
<div class="s-produto__carrossel-botao"></div>
<div class="s-produto__carrossel-botao"></div>
<div class="s-produto__carrossel-botao"></div>
</div>
</div>
<div class="s-produto__informacoes">
<div class="s-produto__breadcrumbs">
<span><a href="{% url 'store' %}">Loja</a></span>
<span><a href="{% url 'store' product.category.slug %}">{{ product.category.name }}</a></span>
<span><a href="{% url 'store' %}{{ product.category.slug }}-{{ product.product_type.slug }}">{{ product.product_type.name }}</a></span>
<span>
<p>{{ product.name }}</p>
</span>
</div>
<div class="s-produto__infos">
<h1 class="s-produto__titulo">{{ product.name }}</h1>
<p class="s-produto__preco">R$ {{ product.price }}</p>
<div class="s-produto__cor">
<p class="s-produto__cor-nome">Cor: <span>{{ selected_color.name }}</span></p>
<div class="s-produto__cores">
{% for color in colors %}
<a
href = "{% url 'view_product' product.id color.id %}"
class="s-produto__cores-item"
style="background-color: {{ color.code }};"
></a>
{% endfor %}
</div>
</div>
{% if has_stock %}
{% if sizes %}
<form method = "POST" action = "{% url 'add_to_cart' product.id %}">
{% csrf_token %}
<div class="s-produto__tamanho">
<div class="s-produto__tamanhos">
{% for size in sizes %}
<div class="menu__tamanho"> <!--Needs to have menu__tamanho class for the javascript-->
<div class="s-produto__tamanhos-item">{{ size }}</div>
<input class="menu__checkbox" type="radio" name="size" value="{{ size }}"> <!--menu__checkbox used in the produto.js-->
</div>
{% endfor %}
</div>
</div>
<input type="hidden" name="color" value="{{ selected_color.id }}">
<button type="submit" class="s-produto__adicicionar">Adicionar à sacola</button>
</form>
{% endif %}
{% else %}
<h3>Item fora de estoque</h3>
{% endif %}
</div>
<div class="s-produto__descricao">
<p class="s-produto__descricao-titulo">Descrição do produto</p>
<div class="s-produto__descricao-textos">
<p>
{{ product.description }}
</p>
<p>
COMPOSIÇÃO <br />
{{ product.composition }}
</p>
<p>
CÓDIGO DO PRODUTO <br />
Ref: <span>{{ product.id }}</span>
</p>
</div>
</div>
</div>
</section>
{% if similars %}
<section class="similares">
<h2 class="similares__titulo">
Gostou desse produto? Veja itens similares
</h2>
<div class="similares__container">
{% for similar in similars %}
<a
href="{% url 'view_product' similar.id %}"
class="produto"
>
<div class="produto__imagem">
<img
src="{{ similar.image.url }}"
alt="Imagem do Produto"
/>
</div>
<div class="produto__textos">
<p class="produto__titulo">{{ similar.name }}</p>
<div class="produto__preco">
<p class="produto__avista">R$ {{ similar.price }}</p>
</div>
</div>
</a>
{% endfor %}
</div>
</section>
{% endif %}
</main>
<script type="text/javascript" src="{% static 'js/produto.js' %}"></script>
{% endblock %}
Now, update the view_product
function in the views.py
file to include the queryset for similar products in the context. This allows the "Similar Products" section to render dynamically based on the defined criteria.
def view_product(request, product_id, id_color = None) :
has_stock = False
sizes = {}
colors = {} #? needs to be declared
selected_color = None
product = Product.objects.get(id=product_id) #? id parameter is created automatically by django
item_stock = ItemStock.objects.filter(product = product, quantity__gt = 0) #? gets the product that has more than 0 quantity (queryset lookup)
if len(item_stock) > 0 :
has_stock = True #? necessary in order to do a if on the html. if the product is out of stock, will show "Out of Stock"
colors = {item.color for item in item_stock} #? gets the colors of all products, uses sets '{}' to avoid duplicate colors
if id_color :
selected_color = Color.objects.get(id = id_color) #? gets the color object from the Color class
item_stock = ItemStock.objects.filter(product = product, quantity__gt = 0, color__id = id_color) #? gets the color id attribute from the Color class (that is automatically created)
sizes = {item.size for item in item_stock} #? gets the sizes of all products
similars = Product.objects.filter(category__id=product.category.id, product_type__id=product.product_type.id).exclude(id=product.id)[:4] #? gets all products that are not the same as the current one
context = {'product': product, "has_stock" : has_stock, "colors" : colors, "sizes" : sizes, "selected_color" : selected_color, "similars" : similars}
return render(request, 'view_product.html', context)
Note: The "Similar Products" section will display only the first four similar products, ensuring a concise and visually appealing layout.

Last updated