Django
Carregando, aguarde alguns segundos.

4 - QuerySet

Um QuerySet é uma coleção de dados de um banco de dados.

Um QuerySet é construído como uma lista de objetos.

Os QuerySets facilitam a obtenção dos dados de que você realmente precisa, permitindo que você filtre e ordene os dados.

4.1 - QuerySet de livros

Neste tutorial consultaremos dados da tabela Livros.

id primeiro_nome ultimo_nome
1 O Dia de Amanhã Jorge Dias
2 O Sol Amarelo Maria Amélia
3 A Viagem Joana Martins
4 Carros em Fuga José Silva
5 O Baralho do Mágico Ana Torres

4.1.1 - View

As views são funções para conter código mesclando templates e dados para serem retornados como resposta-http aos clientes.

4.1.1.1 - Função view_comum(request, meus_livros)

A função view_comum(request, meus_livros) tem as instruções básicas comums às views, onde a alteração ocorre no conjunto de itens retornados na consulta de dados.

São dois argumentos da função:

  • request: dados da requisição do cliente
  • meus_livros: itens da consulta de dados da tabela Livros

São três instruções no bloco da função:

  • carregamento do template
  • atribuição dos dados ao contexto
  • retorno da resposta-html com a renderização do template com os dados do contexto

São importados dois módulos de objetos utilizados no bloco da função:

  • HttpResponse
  • loader
from django.http import HttpResponse
from django.template import loader
#
def view_comum(request, meus_livros):
    template = loader.get_template('template.html')
    context = {'meus_livros': meus_livros,}
    return HttpResponse(template.render(context,request))

Em views.py, temos views para teste chamadas teste_01, teste_02, teste_03 e assim por diante, para testarem diferentes consultas.

No exemplo abaixo utilizamos o método .all() para obter todos os registros e campos do modelo Livros:

livros/views.py:
import Livros
def teste_01(request):
    meus_livros = Livros.objects.all()
    return view_comum(meus_livros)

O objeto é colocado em uma variável chamada meus_livros, e é enviado para o modelo por meio do contextobjeto como meus_livros, e se parece com isso:

<QuerySet [
  <Livros: Livros object (1)>,
  <Livros: Livros object (2)>,
  <Livros: Livros object (3)>,
  <Livros: Livros object (4)>,
  <Livros: Livros object (5)>
]>

Como você pode ver, nosso modelo Livros contém 5 registros e são listados dentro do QuerySet como 5 objetos.

No template você pode usar o meus_livros objeto para gerar conteúdo:

4.1.2 - Template

template.html:

<table> border='1'>
    <tr>>
        <th>ID</th>
        <th>Firstname</th>
        <th>Lastname</th>
    </tr>>
    {% for x in meus_livros %}
        <tr>>
            <td>{{ x.id }}</td>
            <td>{{ x.titulo_autor }}</td>
            <td>{{ x.lastname }}</td>
        </tr>>
    {% endfor %}
</table>>

4.2 - Obter Dados

Existem diferentes métodos para obter dados de um modelo em um QuerySet.

4.2.1 - Método values()

O método values() permite retornar cada objeto como um dicionário Python, com os nomes e valores como pares chave/valor:

livros/views.py:
from .models import Livros
def teste_02(request):
    meus_livros = Livros.objects.all().values()
    return view_comum(request,meus_livros)

4.2.2 - Método values_list()

O método values_list() retorna as colunas especificadas.

View: livros/views.py:

from .models import Livros
def teste_03(request):
    meus_livros = Livros.objects.values_list('titulo_autor')
    return view_comum(request,meus_livros)

4.2.3 - Retornar linhas específicas

Você pode filtrar a pesquisa para retornar apenas linhas/registros específicos, usando o método filter().

View: livros/views.py:

import Livros
def teste_04(request):
    meus_livros = Livros.objects.filter(titulo_autor='Emil').values()
    return view_comum(meus_livros)

4.3 - Filtro QuerySet

O método filter() é usado para filtrar sua pesquisa e permite retornar apenas as linhas que correspondem ao termo de pesquisa.

Como aprendemos no capítulo anterior, podemos filtrar os nomes dos campos como este:

Exemplo

Retorna apenas os registros onde o primeiro nome é 'Emil':

meus_livros = Livros.objects.filter(titulo_autor='Emil').values()

Em SQL, a instrução acima seria escrita assim:

SELECT * FROM livros WHERE titulo_autor = 'Emil';

O método filter() recebe os argumentos como **kwargs (argumentos de palavras-chave), então você pode filtrar em mais de um campo separando-os por vírgula.

4.3.1 - Condição E (and)

Exemplo: retornar os registros onde o sobrenome é "Refsnes" e o id é 2.

meus_livros = Livros.objects.filter(lastname='Refsnes', id=2).values()

Em SQL, a instrução acima seria escrita assim:

SELECT * FROM livros WHERE lastname = 'Refsnes' AND id = 2;

4.3.2 - Condição OU (or)

Retornar registros onde o nome é Emil ou o nome é Tobias (significando: retornar registros que correspondam a qualquer consulta, não necessariamente a ambos) não é tão fácil quanto o exemplo AND acima.

Podemos usar vários métodos filter(), separados por uma barra vertical |. Os resultados serão mesclados em um modelo.

Exemplo: retornar registros onde o primeiro nome é "Emil" ou Tobias":

meus_livros = Livros.objects.filter(titulo_autor='Emil').values() | Livros.objects.filter(titulo_autor='Tobias').values()

Outro método comum é importar e usar expressões Q:

Exemplo: retorna registros onde o primeiro nome é "Emil" ou Tobias".

from .models import Livros
from django.db.models import Q
#
def teste_05(request):
    meus_livros = Livros.objects.filter(Q(titulo_autor='Emil') | Q(titulo_autor='Tobias')).values()
    return view_comum(meus_livros)

Em SQL, a instrução acima seria escrita como:

SELECT * FROM livros WHERE titulo_autor = 'Emil' OR titulo_autor = 'Tobias';

4.3.3 - Pesquisas de campo

O Django tem sua própria maneira de especificar instruções SQL e cláusulas WHERE.

Para especificar onde cláusulas no Django, use "pesquisas de campo".

Pesquisas de campo são palavras-chave que representam palavras-chave SQL específicas.

Exemplo:

.filter(firstname__startswith='L');

É o mesmo que a instrução SQL:

WHERE titulo_autor LIKE 'L%'

A instrução acima retornará registros onde titulo_autor começa com 'L'.

4.3.4 - Sintaxe de pesquisas de campo

Todas as palavras-chave de pesquisa de campo devem ser especificadas com o nome do campo, seguido por dois (!) caracteres de sublinhado e a palavra-chave.

Em nosso modelo de Livros, a declaração seria escrita assim:

Exemplo: Retorne os registros onde o nome começa com a letra 'L'.

meus_livros = Livros.objects.filter(firstname__startswith='L').values()

4.3.5 - Referência de pesquisas de campo

Uma lista de todas as palavras-chave de pesquisa de campo:

Palavra-chave Descrição
contains Contém a frase
icontains O mesmo que contains, mas não diferencia maiúsculas de minúsculas
date Corresponde a uma data
day Corresponde a uma data (dia do mês, 1-31) (para datas)
endswith Termina com
iendswith O mesmo que endswidth, mas não diferencia maiúsculas de minúsculas
exact Uma correspondência exata
iexact O mesmo que exact, mas não diferencia maiúsculas de minúsculas
in Corresponde a um dos valores
isnull Corresponde a valores NULL
gt Maior que
gte Maior ou igual a
hour Corresponde a uma hora (para datetimes)
lt Menor que
lte Menor ou igual a
minute Corresponde a um minuto (para datas e horários)
month Corresponde a um mês (para datas)
quarter Corresponde a um trimestre do ano (1-4) (para datas)
range Correspondência entre
regex Corresponde a uma expressão regular
iregex O mesmo que regex, mas não diferencia maiúsculas de minúsculas
second Corresponde a um segundo (para datetimes)
startswith Começa com
isstartswith Igual a startswith, mas não diferencia maiúsculas de minúsculas
time Corresponde a uma hora (para datetimes)
week Corresponde a um número de semana (1-53) (para datas)
week_day Corresponde a um dia da semana (1-7) 1 é domingo
iso_week_day Corresponde a um dia da semana ISO 8601 (1-7) 1 é segunda-feira
year Corresponde a um ano (para datas)
iso_year Corresponde a um ano ISO 8601 (para datas)

4.4 - Order By

Para classificar QuerySets, o Django usa o método order_by().

Exemplo: Ordene o resultado em ordem alfabética por nome.

meus_livros = Livros.objects.all().order_by('titulo_autor').values()

Em SQL, a instrução acima seria escrita assim:

SELECT * FROM livros ORDER BY titulo_autor;

4.4.1 - Ordem decrescente

Por padrão, o resultado é classificado em ordem crescente (o valor mais baixo primeiro), para alterar a direção para decrescente (o valor mais alto primeiro), use o sinal de menos (NOT), -na frente do nome do campo:

Exemplo: Ordene o primeiro nome do resultado de forma decrescente.

meus_livros = Livros.objects.all().order_by('-titulo_autor').values()

Em SQL, a instrução acima seria escrita assim:

SELECT * FROM livros ORDER BY titulo_autor DESC;

4.4.2 - Pedidos múltiplos

Para ordenar por mais de um campo, separe os nomes dos campos com uma vírgula no método order_by().

Exemplo: ordene o resultado primeiro por sobrenome crescente e depois decrescente em id.

meus_livros = Livros.objects.all().order_by('lastname', '-id').values()

Em SQL, a instrução acima seria escrita assim:

SELECT * FROM livros ORDER BY lastname ASC, id DESC;
Arduino
Coautor
Betobyte
Autor
Autores
||| Áreas ||| Estatística ||| Python ||| Projetos ||| Dicas & Truques ||| Quantum ||| Django || Python para Iniciantes || Python Básico || Matplotlib || Numpy || Seaborn || Pandas || Django || Estatística para Cientistas de Dados || Python com ML Básico || Python com ML Básico || Aulas | Introdução (models, views, templates) | Livraria Exemplo (ambiente virtual, projeto, aplicativo, banco de dados) | Templates (templates HTML e tags django) | QuerySets (consultas de dados com querysets) |