Aula 11 – Loja Online – Ecommerce – Django – Consultas ao Banco de Dados

More videos
Views
   

Loja Virtual – Ecommerce – Django – Consultando o Banco de Dados via shell

Lookups

Na aula passada construímos a parte referente a upload de imagens dos produtos.

Vimos que o django na hora do upload da imagem, cria um sufixo aleatório para dá uma identidade única as imagens e evitar que imagem que tenham o mesmo nome por coincidência, seja subscrita no seu CDN na hora de fazer upload de novas imagens.

Ele também elimina os espaços em branco entre palavras, substituindo por underscore, para evitar problemas, já que espaço em branco em nomes de pastas e arquivos sempre podem ocasionar contratempos inesperados.

Consultando o Banco de Dados via shell

Consultando o Banco de Dados via shell

Lookups é a forma como são especificadas as condições na cláusula WHERE de um SQL.

Condições da pesquisa

As condições são especificadas como argumentos de palavra-chave para os métodos de pesquisa (QuerySet) como filter(), exclude() e get().

Contains e o icontains verifica se a string fornecida está contida no campo valor no banco de dados. O contains é traduzido para LIKE e o icontains para ILIKE em SQL.

O contains diferencia maiúsculas de minúsculas (case-sensitive) o icontains não (case-insensitive).

Vamos abrir o shell do django.

python manage.py shell

O prompt muda para um prompt python ( >>> )

Faça o seguinte import.

from products.models import Product

Vamos dá uma olhada no queryset um pouco mais profundamente.

queryset = Product.objects.all()
queryset

Saída:

<Queryset [<Product: Camiseta>, <Product: Tênis>]>

Semelhante ao comando sql:

SELECT * FROM products_product;

A gente pode também filtrar.

qs = Product.objects.filter(title__contains = "seta")
qs

Saída:

<Queryset [<Product: Camiseta>]>

Semelhante ao comando sql:

SELECT * FROM products_product;
WHERE title LIKE '%seta%';

Vamos buscar algo que não tenha.

qs = Product.objects.filter(title__contains = "carro")
qs

Saída:

<Queryset []>

qs = Product.objects.filter(description__icontains = "edição limitada")
qs

Saída:

<Queryset [<Product: Camiseta>]>

qs = Product.objects.filter(description__icontains = "tecnologia inovadora")

Saída:

<Queryset [<Product: Tênis>]>

qs = Product.objects.filter(title__icontains = "Cami", description__iexact = 'Abc')

Saída:

<Queryset []>

qs = Product.objects.filter(title__icontains = "Cami", description__iexact = 'Essa camiseta é uma edição limitada, é exclusiva e apenas algumas unidades estão disponíveis.')

Saída:

<Queryset [<Product: Camiseta>]>


qs = Product.objects.filter(pk = 1)
qs

Saída:

<Queryset [<Product: Camiseta>]>


qs = Product.objects.filter(id = 1)
qs

Saída:

<Queryset [<Product: Camiseta>]>

Tanto faz usar id ou pk.

Se tentar acessar com o get um id que não existe

qs = Product.objects.get(pk = 4)

Será mostrada uma mensagem de erro:

Traceback (most recent call last):
File “<console>”, line 1, in <module>
File “/home/toticavalcanti/django_ecommerce/lib/python3.6/site-packages/django/db/models/manager.py”, line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File “/home/toticavalcanti/django_ecommerce/lib/python3.6/site-packages/django/db/models/query.py”, line 399, in get
self.model._meta.object_name
products.models.Product.DoesNotExist: Product matching query does not exist.

Isso é considerado um erro de servidor.

É por isso que temos o get_object_or_404 na function product_detail_view() no src/products/views.py.

Vamos modificar o src/products/views.py para lidar com esse erro de uma forma um pouco melhor:


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(ProductDetailView, 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):
    #traz todos os produtos do banco de dados sem filtrar nada 
    queryset = Product.objects.all()
    template_name = "products/detail.html"
    
    def get_context_data(self):
        context = super(ProductDetailView, self).get_context_data(*args, **kwargs)
        print(context)
        return context

#Function Based View
def product_detail_view(request, pk = None, *args, **kwargs):
    #instance = Product.objects.get(pk = pk) #get the object id
    #instance = get_object_or_404(Product, pk = pk)
    try:
        instance = Product.objects.get(id = pk)
    except Product.DoesNotExist:
        print("Nenhum produto encontrado aqui!")
        raise Http404("Esse produto não existe!")

    context = {
        'object': instance
    }
    return render(request, "products/detail.html", context)

Acesse um produto que não exista e veja o print no console do servidor e o raise http404 no browser.

Vamos modificar de novo src/products/views.py para lidar com esse erro de uma forma melhor ainda, menos verbosa, vamos deletar tudo que fizemos no passo anterior com o try except e substituir pelo 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 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):
        #context = super(ProductDetailView, 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):
    #traz todos os produtos do banco de dados sem filtrar nada 
    queryset = Product.objects.all()
    template_name = "products/detail.html"
    
    def get_context_data(self):
        context = super(ProductDetailView, self).get_context_data(*args, **kwargs)
        print(context)
        return context

#Function Based View
def product_detail_view(request, pk = None, *args, **kwargs):
    #instance = Product.objects.get(pk = pk) #get the object id
    #instance = get_object_or_404(Product, pk = pk)
    qs = Product.objects.filter(id = pk)
    if qs.exists():
        instance = qs.first()
    else:
        raise Http404("Esse produto não existe!")

    context = {
        'object': instance
    }
    return render(request, "products/detail.html", context)

qs.exists() vs qs.count()

O queryset tem um método mais eficiente para o banco de dados do que o qs.exists(), que é o qs.count(), então vamos usar ele ao invés do qs.exists().

Vamos modificar novamente o src/products/views.py, substituindo o qs.exists() pelo qs.count() == 1:


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(ProductDetailView, 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):
    #traz todos os produtos do banco de dados sem filtrar nada 
    queryset = Product.objects.all()
    template_name = "products/detail.html"
    
    def get_context_data(self):
        context = super(ProductDetailView, self).get_context_data(*args, **kwargs)
        print(context)
        return context

#Function Based View
def product_detail_view(request, pk = None, *args, **kwargs):
    #instance = Product.objects.get(pk = pk) #get the object id
    #instance = get_object_or_404(Product, pk = pk)
    if qs.count() == 1:
        instance = qs.first()
    else:
        raise Http404("Esse produto não existe!")

    context = {
        'object': instance
    }
    return render(request, "products/detail.html", context)

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 é o 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/lookups

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 20 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>