Aula 12 – Ecommerce – Django – Custom Model Managers

More videos
Views
   

Loja Virtual – Ecommerce – Django – Custom Model Managers

Custom Model Managers ou Gestores de Modelos Personalizados

Vimos na aula passada, como fazer consultas ao banco pesquisando os produtos cadastrados através do queryset.

Nós fizemos isso no modelo com a ajuda do objects.

Lembra?

queryset = Product.objects.all()

Custom Model Managers

Custom Model Managers

Objects são considerados gerenciadores de modelos.

Um “manager” é a interface através da qual as consultas de banco de dados são fornecidas para os modelos do Django.

Padrão

Por padrão, o Django adiciona um Manager com o nome de objects para cada classe de modelo Django.

Pelo menos um Manager existe para cada modelo em uma aplicação Django.

Eles  nos ajuda a fazer coisas como as querysets ou uma chamada ao próprio modelo.

Objects

objects representa o gerente de modelo o Custom Model Managers.

Filtro

O filtro é um método do Custom Model Managers que nos permite fazer um conjunto de consultas, uma chamada get, etc.

Você pode usar um Manager personalizado em um modelo particular estendendo a classe base do Manager e instanciando seu Manager personalizado em seu modelo.

Porque usar um Custom Model Managers?

Existem dois motivos que fariam você personalizar um Manager: para adicionar métodos extra ao Manager, e/ou modificar o QuerySet inicial que o manager retorna.

Construção

Vamos fazer um Custom Model Managers um pouco mais eficaz para o nosso modelo produto.

Estratégia

Eu poderia querer obter um get object or 404, mas, talvez eu queira usar alguma forma de encontrar uma instância sem ser um get object or 404, ou um exception error.

Então, vamos lá, nosso Custom Model Manager, que vai extender o Default Model Manager.

Vá no src/products/models.py e acrescente o que tá em laranja.


from django.db import models

class ProductManager(models.Manager):
    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)

    objects = ProductManager()
    
    #python 3
    def __str__(self):
        return self.title
    #python 2
    def __unicode__(self):
        return self.title

Criamos a classe ProductManager e dentro dela definimos o método get_by_id.

Dentro fizemos uma queryset para pegar o produto pelo id, ou seja, o filter irá retonar uma queryset com um só produto.

No qs.count() == 1 testamos se a queryset tá vazia ou tem um e apenas um produto, se tiver retorna o produto, senão retorna None.

O objects = ProductManager() é a chamada da nossa classe.

No src/products/views.py, modifique a FBV product_detail_view e a CBV ProductDetailView para que fique assim:

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 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):
    #queryset = Product.objects.all()
    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)

 Na get_object da ProductDetailView (CBV), assim como na product_detail_view(FBV), pegamos o pk pelo argumento na URL através do kwargs, aí a gente chama o método do nosso Custom Model Managers que a gente criou get_by_id passando o pk.

Se a instância retornar None, a saída será um raise Http404(“Esse produto não existe!”), caso contrário, é porque o produto existe e o produto é renderizado na tela do browser.

Note que o queryset logo abaixo da declaração da ProductDetailView não é mais necessário, por isso está comentado, pode remover ele se quiser.

Faça o teste e acesse um produto existente e outyro que não exista, exemplo:

Usando a CBV:

http://127.0.0.1:8000/products/1

http://127.0.0.1:8000/products/564354

Usando a FBV:

http://127.0.0.1:8000/products-fbv/2

http://127.0.0.1:8000/products-fbv/2736

Na próxima aula veremos como personalizar querysets (Featured Custom QuerySets).

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/custom_model_managers

Obrigado, até a próxima e bons estudos. 😉

Increva-se

Inscreva-se agora e receba um e-mail assim que eu publicar novo conteúdo.

Concordo em me inscrever no blog Código Fluente

Você poderá cancelar sua inscrição a qualquer momento.

(Visited 54 times, 1 visits today)
About The Author
-

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>