Aula 59 - Loja Online - Django - Gerenciador dos Pedidos
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:
Melhore seu NETWORKING
Participe de comunidades de desenvolvedores:
Fiquem a vontade para me adicionar ao linkedin.
Código final da aula:
Quer aprender python3 de graça e com certificado? Acesse então:
Toti:
Backing track / Play-along:
Código Fluente
Putz!
Aula 59 - Loja Online - Django - Gerenciador dos Pedidos
Vamos dá uma refatorada no código e trazer uma parte do código que tá no
view.py do
carts para o
models.py do
orders.
Abra o
models.py do
order e acrescente o código que tá em
azul.
O que o código em
azul faz é o seguinte, cria a classe
OrderManager, ou seja,
gerenciador de pedidos.
Essa classe tem o método
new_or_get() que cria e retorna uma
Order, se não existir nenhum pedido com essa associação de
billing_profile e
carrinho, caso já exista um Order com essa associação, ele só retorna esse pedido já existente.
django_ecommerce/e_commerce/orders/models.py
import math
from django.db import models
from django.db.models.signals import pre_save, post_save
from billing.models import BillingProfile
from carts.models import Cart
from e_commerce.utils import unique_order_id_generator
ORDER_STATUS_CHOICES = (
('created', 'Criado'),
('paid', 'Pago'),
('shipped', 'Enviado'),
('refunded', 'Devolvido'),
)
class OrderManager(models.Manager):
def new_or_get(self, billing_profile, cart_obj):
created = False
qs = self.get_queryset().filter(
billing_profile = billing_profile,
cart = cart_obj,
active = True)
if qs.count() == 1:
obj = qs.first()
else:
obj = self.model.objects.create(
billing_profile = billing_profile,
cart=cart_obj)
created = True
return obj, created
class Order(models.Model):
billing_profile = models.ForeignKey(BillingProfile, on_delete=models.CASCADE, null = True, blank = True)
order_id = models.CharField(max_length = 120, blank = True)
# billing_profile = ?
# shipping_address = ?
# billing_address
cart = models.ForeignKey(Cart, on_delete=models.CASCADE, null = True)
status = models.CharField(max_length = 120, default = 'created', choices = ORDER_STATUS_CHOICES )
shipping_total = models.DecimalField(default = 5.99, max_digits = 100, decimal_places = 2)
total = models.DecimalField(default = 0.00, max_digits = 100, decimal_places = 2)
active = models.BooleanField(default=True)
def __str__(self):
return self.order_id
objects = OrderManager()
def update_total(self):
cart_total = self.cart.total
shipping_total = self.shipping_total
new_total = math.fsum([cart_total, shipping_total])
formatted_total = format(new_total, '.2f')
self.total = formatted_total
self.save()
return new_total
def pre_save_create_order_id(sender, instance, *args, **kwargs):
if not instance.order_id:
instance.order_id = unique_order_id_generator(instance)
# retorna todos os orders com esta instância de cart,
# excluindo aqueles que têm a mesma instância de billing_profile
qs = Order.objects.filter(cart = instance.cart).exclude(billing_profile = instance.billing_profile)
if qs.exists():
qs.update = False
pre_save.connect(pre_save_create_order_id, sender = Order)
def post_save_cart_total(sender, instance, created, *args, **kwargs):
if not created:
cart_obj = instance
cart_total = cart_obj.total
cart_id = cart_obj.id
qs = Order.objects.filter(cart__id=cart_id)
if qs.count() == 1:
order_obj = qs.first()
order_obj.update_total()
post_save.connect(post_save_cart_total, sender=Cart)
def post_save_order(sender, instance, created, *args, **kwargs):
print("Executando")
if created:
print("Atualizando")
instance.update_total()
post_save.connect(post_save_order, sender=Order)
No
views.py do
carts, coloque as alterações em
azul.
O que esse código faz é verificar se existe um
billing_profile para o usuário, para que seja possível atribuir ou criar um
Order associando ao seu
Cart.
Django_ecommerce/e_commerce/carts/views.py
from django.shortcuts import render, redirect
from accounts.forms import LoginForm, GuestForm
from accounts.models import GuestEmail
from billing.models import BillingProfile
from orders.models import Order
from products.models import Product
from .models import Cart
def cart_home(request):
cart_obj, new_obj = Cart.objects.new_or_get(request)
return render(request, "carts/home.html", {"cart": cart_obj})
def cart_update(request):
print(request.POST)
product_id = request.POST.get('product_id')
if product_id is not None:
try:
product_obj = Product.objects.get(id = product_id)
except Product.DoesNotExist:
print("Mostrar mensagem ao usuário, esse produto acabou!")
return redirect("cart:home")
cart_obj, new_obj = Cart.objects.new_or_get(request)
if product_obj in cart_obj.products.all():
cart_obj.products.remove(product_obj)
else:
cart_obj.products.add(product_obj)
request.session['cart_items'] = cart_obj.products.count()
return redirect("cart:home")
def checkout_home(request):
#aqui a gente pega o carrinho
cart_obj, cart_created= Cart.objects.new_or_get(request)
order_obj = None
#se o carrinho acabou de ser criado, ele tá zerado
#ou se o carrinho já existir mas não tiver nada dentro
if cart_created or cart_obj.products.count() == 0:
return redirect("cart:home")
#aqui a order associada ao carrinho
user = request.user
billing_profile = None
login_form = LoginForm()
guest_form = GuestForm()
guest_email_id = request.session.get('guest_email_id')
if user.is_authenticated:
billing_profile, billing_profile_created = BillingProfile.objects.get_or_create(
user=user, email=user.email)
elif guest_email_id is not None:
guest_email_obj = GuestEmail.objects.get(id=guest_email_id)
billing_profile, billing_guest_profile_created = BillingProfile.objects.get_or_create(
email=guest_email_obj.email)
else:
pass
if billing_profile is not None:
order_obj, order_obj_created = Order.objects.new_or_get(billing_profile, cart_obj)
context = {
"object": order_obj,
"billing_profile": billing_profile,
"login_form": login_form,
"guest_form": guest_form
}
return render(request, "carts/checkout.html", context)
É isso, ficamos por aqui e até a próxima. ;)
Código final da aula:
Outros canais
Toti:
Backing track / Play-along:
Código Fluente
Putz!
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:
Nos vemos na próxima então, \o/ 😉 Bons Estudos!