Aula 43 – Loja Online – Django – Carrinho – Cálculo do Total
Aula 43 – Loja Online – Django – Carrinho – Cálculo do Total
Voltar para página principal do blog
Todas as aulas desse curso
Aula 42 Aula 44
Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook
Esse é o link do código fluente no Pinterest
Meus links de afiliados:
Hostinger
Digital Ocean
One.com
Melhore seu NETWORKING
Participe de comunidades de desenvolvedores:
Fiquem a vontade para me adicionar ao linkedin.
E também para me seguir no https://github.com/toticavalcanti.
Código final da aula:
https://github.com/toticavalcanti
Toti:
https://www.youtube.com/channel/UCUEtjLuDpcOvR3mIUr-viOA
Backing track / Play-along:
https://www.youtube.com/channel/UCT3TryVMqTqYBjf5g5WAHfA
Código Fluente
https://www.youtube.com/channel/UCgn-O-88XBAwdG9gUWkkb0w
Putz!
https://www.youtube.com/channel/UCZXop2-CECwyFYmHbhnAkAw
Aula 43 – Loja Online – Django – Carrinho – Cálculo do Total
Nessa aula vamos implementar o cálculo do total do carrinho.
Abra a django_ecommerce/carts/views.py para começarmos.
django_ecommerce/carts/views.py
from django.shortcuts import render
from .models import Cart
def cart_home(request):
cart_obj, new_obj = Cart.objects.new_or_get(request)
products = cart_obj.products.all()
total = 0
for product in products:
total += product.price
print(total)
cart_obj.total = total
cart_obj.save()
return render(request, "carts/home.html", {})
Abra a página de admin para testar.
127.0.0.1:8000/admin/carts/
Para criar o total de forma mais eficiente e funcional, vamos usar signals.
Já usamos signals no gerador de slug dos produtos, no arquivo models.py do products.
No caso do total, será um pouco diferente, porque temos os produtos que tem relacionamento de muitos para muitos.
Mas, o que são signals e para que servem?
O Django inclui um “despachante de sinal” que ajuda no desacoplamento dos aplicativos, permitindo que determidas partes da aplicação sejam notificadas quando ações ocorrerem em outro lugar da mesma aplicação.
Resumindo, os sinais permitem que certos remetentes notifiquem um conjunto de receptores de que alguma ação ocorreu, é o famoso listener do padrão de projetos Observer.
Eles são especialmente úteis quando muitos trechos de código podem estar interessados nos mesmos eventos.
Essencialmente, eles permitem que você envie um “sinal” quando um evento ocorrer para que outras partes do seu aplicativo possam responder.
django_ecommerce/carts/models.py
from django.conf import settings
from django.db import models
from django.db.models.signals import pre_save, post_save, m2m_changed
from products.models import Product
User = settings.AUTH_USER_MODEL
class CartManager(models.manager):
def new_or_get(self, request):
cart_id = request.session.get("cart_id", None)
qs = self.get_queryset().filter(id = cart_id)
if qs.count == 1:
new_obj = False
cart_obj = qs.first()
if request.user.is_authenticated and cart_obj.user is None:
cart_obj.user = request.user
cart_obj.save()
else:
cart_obj = Cart.objects.new(user = request.user)
new_obj = True
request.session['cart_id'] = cart_obj.id
return cart_obj, new_obj
def new(self, user = None):
user_obj = None
if user is not None:
if user.is_authenticated:
user_obj = user
return self.model.objects.create(user = user_obj)
class Cart(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null = True, blank = True)
products = models.ManyToManyField(Product, blank = True)
total = models.DecimalField(default = 0.00, max_digits=100, decimal_places = 2)
subtotal = models.DecimalField(default = 0.00, max_digits=100, decimal_places = 2)
updated = models.DateTimeField(auto_now = True)
timestamp = models.DateTimeField(auto_now_add = True)
objects = CartManager()
def __str__(self):
return str(self.id)
def m2m_changed_cart_receiver(sender, instance, action, *args, **kwargs):
#print(action)
if action == 'post_add' or action == 'post_remove' or action == 'post_clear':
#print(instance.products.all())
#print(instance.total)
products = instance.products.all()
total = 0
for product in products:
total += product.price
if instance.subtotal != total:
instance.subtotal = total
instance.save()
#print(total)
instance.subtotal = total
instance.save()
m2m_changed.connect(m2m_changed_cart_receiver, sender = Cart.products.through)
def pre_save_cart_receiver(sender, instance, *args, **kwargs):
instance.total = instance.subtotal + 10 # considere o 10 como uma taxa de entrega
pre_save.connect(pre_save_cart_receiver, sender = Cart)
Como incluímos o campo subtotal ao nosso carrinho, faça as migrações:
python manage.py makemigrations
python manage.py migrate
Campo subtotal
O campo subtotal é para, por exemplo, ser possível mostrar o total da soma dos produtos e deixar o campo total para a soma geral, ou seja, o subtotal + taxas + frete + … .
Quando a gente clicar em salvar, a pre_save_cart_receiver() vai ser chamada.
Você pode notar que se você selecionar os produtos e salvar, o total não muda, a função receiver tá sendo executada, mas o resultado não tá refletindo no campo total.
É aí que entra o signals.
O fato do produto ter uma relação muitos para muitos, a gente vai usar o signals m2m_changed, para quando selecionarmos os produtos e salvar, o resultado reflita no campo total.
Voltando a Views do Cart como era antes, mas mais enxutinha, só que com as duas variáveis cart_obj e new_obj recebendo o retorno de new_or_get().
django_ecommerce/carts/views.py
from django.shortcuts import render
from .models import Cart
def cart_home(request):
cart_obj, new_obj = Cart.objects.new_or_get(request)
return render(request, "carts/home.html", {})
Abra a página de admin para testar.
Voltar para página principal do blog
Todas as aulas desse curso
Aula 42 Aula 44
Código final da aula:
https://github.com/toticavalcanti
Outros canais
Toti:
https://www.youtube.com/channel/UCUEtjLuDpcOvR3mIUr-viOA
Backing track / Play-along:
https://www.youtube.com/channel/UCT3TryVMqTqYBjf5g5WAHfA
Código Fluente
https://www.youtube.com/channel/UCgn-O-88XBAwdG9gUWkkb0w
Putz!
https://www.youtube.com/channel/UCZXop2-CECwyFYmHbhnAkAw
Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook
Esse é o link do código fluente no Pinterest
Meus links de afiliados:
Hostinger
Digital Ocean
One.com
É isso, ficamos por aqui \o/ e até a próxima 😉
Olá Toti, primeiramente quero agradecer o conteúdo sensacional, meus parabéns e pedir para rever os códigos (if request.user.is_authenticate and cart_obj.user is None:) e (if user.is_authenticate), pois ambos são (is_authenticated)