Aula 13 – Loja Online – Django – Custom QuerySets
Aula 13 – Loja Online – Django – Custom QuerySets
Loja Virtual – Ecommerce – Django – Custom QuerySets
Voltar para página principal do blog
Todas as aulas desse curso
Aula 12 Aula 14
Para baixar o código como está até agora, acesse o link abaixo:
https://github.com/toticavalcanti/django_ecommerce/tree/featured_custom_querySets
Consultas personalizadas para produtos em destaque e ativos
Vimos na aula passada, como fazer um Custom Model Managers (gestores de modelos personalizados).
O Manager é a interface que interage com o banco de dados
No Django, os Custom Managers são uma ótima maneira de organizar a lógica de consulta reutilizável.
Na documentação do Django é dito que há dois motivos pelos quais você pode personalizar um gerenciador de modelo:
- Para adicionar métodos extras do Gerenciador
- Modificar o QuerySet inicial que o Manager retorna.
Agora vamos customizar queryset.
Dois novos campos no modelo product
Vamos introduzir dois novos campos ao nosso modelo product.
Um será o featured, ele será do tipo booleano, e definirá se um produto tá em destaque ou não.
O outro será o active, também booleano, que definirá se o produto está ativo ou não.
Vamos criar dentro da classe ProductManager, que é nosso model custom manager, os métodos:
- featured, que vai devolver os produtos em destaque, ou seja, com featured igual a true.
- all que retorna todos os produtos ativo.
- e também vamos sobrescrever o get_queryset.
E para poder realmente chamar um conjunto de queries (query set) e conectá-las com nossa própria query personalizada (Custom QuerySets), iremos criar a classe ProductQuerySet.
E dentro dela criaremos dois métodos:
- O active que vai retornar os produtos ativos, isto é, com o campo active igual a true;
- E o featured, que vai retornar os produtos ativos e em destaque, ou seja, que além do campo active está como true, o campo featured também está como true.
Dessa maneira, a gente consegue por exemplo, fazer a seguinte chamada:
queryset = Product.objects.all().featured()
Sem a Featured Custom QuerySets a chamada teria que ser:
self.get_queryset().filter(featured = True)
Sem a QuerySets personalizada, não conseguiríamos encadear nossa query.
A gente vai acrescentar os métodos featured e active na queryset padrão.
Em src/products/models.py, insira o que tá em laranja.
from django.db import models
#Custom queryset
class ProductQuerySet(models.query.QuerySet):
def active(self):
return self.filter(active = True)
def featured(self):
return self.filter(featured = True, active = True)
class ProductManager(models.Manager):
def get_queryset(self):
return ProductQuerySet(self.model, using = self._db)
def all(self):
return self.get_queryset().active()
def featured(self):
#return self.get_queryset().filter(featured = True)
return self.get_queryset().featured()
def get_by_id(self, id):
qs = self.get_queryset().filter(id = id)
if qs.count() == 1:
return qs.first()
return None
# Create your models here.
class Product(models.Model): #product_category
title = models.CharField(max_length=120)
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=20, default=100.00)
image = models.FileField(upload_to = 'products/', null = True, blank = True)
featured = models.BooleanField(default = False)
active = models.BooleanField(default = True)
objects = ProductManager()
#python 3
def __str__(self):
return self.title
#python 2
def __unicode__(self):
return self.title
Migrações
Como acrescentamos o campo featured ao nosso modelo, é necessário fazer as migrações para o banco.
Para isso rode:
python manage.py makemigrations
python manage.py migrate
Teremos uma view que lida apenas com o featured.
Abra o src/products/views.py e insira o que tá em laranja.
from django.http import Http404
from django.views.generic import ListView, DetailView
from django.shortcuts import render, get_object_or_404
from .models import Product
class ProductFeaturedListView(ListView):
template_name = "products/list.html"
def get_queryset(self, *args, **kwargs):
return Product.objects.featured()
class ProductFeaturedDetailView(DetailView):
queryset = Product.objects.all().featured()
template_name = "products/featured-detail.html"
#def get_queryset(self, *args, **kwargs):
#request = self.request
#return Product.objects.featured()
#Class Based View
class ProductListView(ListView):
#traz todos os produtos do banco de dados sem filtrar nada
queryset = Product.objects.all()
template_name = "products/list.html"
# def get_context_data(self, *args, **kwargs):
# context = super(ProductListView, self).get_context_data(*args, **kwargs)
# print(context)
# return context
#Function Based View
def product_list_view(request):
queryset = Product.objects.all()
context = {
'object_list': queryset
}
return render(request, "products/list.html", context)
#Class Based View
class ProductDetailView(DetailView):
template_name = "products/detail.html"
def get_context_data(self, *args, **kwargs):
context = super(ProductDetailView, self).get_context_data(*args, **kwargs)
print(context)
return context
def get_object(self, *args, **kwargs):
pk = self.kwargs.get('pk')
instance = Product.objects.get_by_id(pk)
if instance is None:
raise Http404("Esse produto não existe!")
return instance
#Function Based View
def product_detail_view(request, pk = None, *args, **kwargs):
instance = Product.objects.get_by_id(pk)
print(instance)
if instance is None:
raise Http404("Esse produto não existe!")
context = {
'object': instance
}
return render(request, "products/detail.html", context)
Note que a ProductFeaturedListView é muito parecida com a ProductListView, assim como a ProductFeaturedDetailView também é bem parecida com a ProductDetailView.
Utilizamos Product.objects.featured() ao invés de Product.objects.all(), porque temos nosso método featured na classe ProductManager, que é nosso model custom manager.
O método featured faz o filtro devolvendo todos os products ativos e com featured setado como true.
Ele é a nossa query personalizada.
Criamos duas novas views, a ProductFeaturedListView e a ProductFeaturedDetailView.
Precisamos configurar as urls delas.
Abra o arquivo src/e_commerce/urls.py e faça as alterações abaixo:
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path
from products.views import (ProductListView,
product_list_view,
ProductDetailView,
product_detail_view,
ProductFeaturedListView,
ProductFeaturedDetailView)
from .views import home_page, about_page, contact_page, login_page, register_page
urlpatterns = [
path('', home_page),
path('about/', about_page),
path('contact/', contact_page),
path('login/', login_page),
path('register/', register_page),
path('featured/', ProductFeaturedListView.as_view()),
path('featured/<int:pk>/', ProductFeaturedDetailView.as_view()),
path('products/', ProductListView.as_view()),
path('products-fbv/', product_list_view),
path('products/', ProductDetailView.as_view()),
path('products-fbv/', product_detail_view),
path('admin/', admin.site.urls),
]
if settings.DEBUG:
urlpatterns = urlpatterns + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Não podemos esquecer do template featured-detail.html, então, crie ele dentro da pasta src/products/templates/product/ e coloque:
{{ object.title }}
{{ object.description }}
{% if object.image %}
<img src='{{ object.image.url }}' class='img-fluid'/>
{% endif %}
Vamos fazer a mesma coisa que fizemos na tag img no featured-detail.html no /products/templates/products/detail.html
{{ object.title }}
{{ object.description }}
{% if object.image %}
<img src='{{ object.image.url }}' class='img-fluid'/>
{% endif %}
Na próxima aula veremos SlugField.
Um slug é um rótulo curto para algo, contendo apenas letras, números, sublinhados ou hifens.
Eles geralmente são usados em URLs.
É isso!
Aula 12 Aula 14
Todas as aulas desse curso
Voltar para página principal do blog
Curta a página do Código Fluente no Facebook
https://www.facebook.com/Codigofluente-338485370069035/
Vou deixar meu link de referidos na digitalocean pra vocês.
Quem se cadastrar por esse link, ganha $100.00 dólares de crédito na digitalocean:
Digital Ocean
Esse outro link é da one.com:
One.com
Para baixar o código como está até agora, acesse o link abaixo:
https://github.com/toticavalcanti/django_ecommerce/tree/featured_custom_querySets
Obrigado, até a próxima e bons estudos. 😉