Dominando Django QuerySets: Um guia abrangente com exemplos práticos

Mastering Django QuerySets: A Comprehensive Guide with Practical Examples

Table of Contents

    Ao trabalhar com Django, entender QuerySets é crucial para interagir eficientemente com seu banco de dados. Neste tutorial, vou guiá-lo pelos detalhes de QuerySets usando um modelo Contact simples. Ao longo do caminho, explicarei o que cada comando faz, por que é útil e como você pode aplicá-lo a cenários do mundo real. Se você está apenas começando com Django ou quer aprimorar suas habilidades, você está no lugar certo.

    Preparando o cenário: o modelo de contato

    Vamos começar criando um pequeno modelo Contact. Imagine que você está construindo um catálogo de endereços onde cada contato tem um primeiro nome, sobrenome e e-mail. Veja como isso se parece no Django:

     from django.db import models class Contact(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) email = models.EmailField(unique=True) def __str__(self): return f"{self.first_name} {self.last_name}"

    Este modelo é bem direto. Os campos first_name e last_name são CharFields com um comprimento máximo de 50 caracteres, enquanto o campo email é único, garantindo que não haja endereços de email duplicados. O método __str__ retorna uma boa representação do contato — perfeito para depuração ou exibição de dados.

    Execute suas migrações para aplicar este modelo ao seu banco de dados:

     python manage.py makemigrations python manage.py migrate

    Com o modelo pronto, vamos mergulhar nos QuerySets.

    O que é um QuerySet?

    Um QuerySet é essencialmente uma coleção de consultas de banco de dados. Pense nisso como uma maneira de recuperar, filtrar e manipular dados do seu banco de dados. A beleza dos QuerySets é que eles são preguiçosos, o que significa que eles não atingem o banco de dados até que você os avalie explicitamente. Isso os torna poderosos e eficientes.

    Vamos preencher nosso banco de dados com alguns dados de exemplo antes de explorar QuerySets.

    Adicionando dados de amostra

    Abra o shell do Django para criar alguns contatos:

     python manage.py shell

    Dentro da concha:

     from app.models import Contact Contact.objects.create(first_name="Alice", last_name="Smith", email="alice@example.com") Contact.objects.create(first_name="Bob", last_name="Jones", email="bob@example.com") Contact.objects.create(first_name="Charlie", last_name="Brown", email="charlie@example.com") Contact.objects.create(first_name="Diana", last_name="Prince", email="diana@example.com")

    Agora temos alguns dados para trabalhar. Vamos mergulhar em QuerySets e ver o que podemos fazer.

    Recuperando todos os registros

    O QuerySet mais simples é Contact.objects.all(). Ele recupera todos os registros da tabela Contact.

     contacts = Contact.objects.all() print(contacts)

    Você notará que ele não busca os dados imediatamente — ele apenas prepara a consulta. Esse é um recurso excelente do QuerySets porque ele evita acessos desnecessários ao banco de dados até que você precise dos dados.

    Por que usar?

    Se você quiser ver tudo na sua tabela, all() é o seu recurso. É também o ponto de partida para encadear outros comandos, que abordaremos a seguir.

    Contagem de Registros

    Quer saber quantos contatos você tem? Use .count().

     count = Contact.objects.all().count() print(f"Total Contacts: {count}")

    Isso envia uma consulta SELECT COUNT(*) ao banco de dados, o que é mais rápido do que carregar todos os objetos e contá-los em Python.

    Por que usar?

    Quando você precisa de um resumo rápido dos seus dados, contar registros é inestimável.

    Verificando a existência

    Se você quer apenas saber se algum registro existe, .exists() é seu amigo.

     exists = Contact.objects.all().exists() print(f"Contacts Exist: {exists}")

    Isso é muito mais rápido do que buscar todos os registros, pois interrompe a pesquisa assim que encontra a primeira correspondência.

    Por que usar?

    Perfeito para cenários como lógica condicional: se houver dados, faça uma coisa; se não, faça outra.

    Recuperando Registros Específicos

    Às vezes, você sabe exatamente o que está procurando. Use .get() para recuperar um único registro por uma condição específica:

     alice = Contact.objects.get(email="alice@example.com") print(f"Found Contact: {alice}")

    A captura

    • Se nenhum registro corresponder, será gerada uma exceção DoesNotExist.
    • Se vários registros corresponderem, ele gera uma exceção MultipleObjectsReturned.

    Filtrando Dados

    E se você quiser todos os contatos com um sobrenome específico? É aí que entra .filter().

     smith_contacts = Contact.objects.filter(last_name="Smith") print(smith_contacts)

    Isso cria um QuerySet de todos os registros correspondentes. Você pode usar várias pesquisas de campo para refinar sua pesquisa:

    • icontains : Pesquisa que não diferencia maiúsculas de minúsculas.
    • startswith : Corresponde ao início de uma string.
    • exato : corresponde ao valor exato.

    Por exemplo:

     emails_with_example = Contact.objects.filter(email__icontains="example.com")

    Por que usar?

    Filtragem é uma das operações mais comuns em qualquer aplicativo baseado em banco de dados. Ela permite que você se concentre nos dados que precisa.

    Excluindo Dados

    Quer tudo, exceto um conjunto específico de registros? Use .exclude():

     non_smith_contacts = Contact.objects.exclude(last_name="Smith") print(non_smith_contacts)

    Resultados de ordenação

    Classificar seus dados é simples com .order_by().

     ordered_contacts = Contact.objects.all().order_by("first_name") print(ordered_contacts)

    Para classificar em ordem decrescente, prefixe o campo com - :

     descending_contacts = Contact.objects.all().order_by("-last_name")

    Agregações

    Se você estiver trabalhando com dados numéricos, o Django tem funções de agregação integradas como Count , Sum , Avg , Max e Min . Vamos contar quantos sobrenomes únicos temos:

     from django.db.models import Count unique_last_names = Contact.objects.values("last_name").distinct().count() print(f"Unique Last Names: {unique_last_names}")

    Anotando QuerySets

    Anotações permitem que você adicione campos computados ao seu QuerySet. Por exemplo, você pode querer criar um campo full_name dinamicamente:

     from django.db.models import Value from django.db.models.functions import Concat contacts = Contact.objects.annotate( full_name=Concat('first_name', Value(' '), 'last_name') ) for contact in contacts: print(contact.full_name)

    Resultados de fatiamento

    Precisa apenas de um subconjunto dos seus dados? Use fatiamento:

     top_two_contacts = Contact.objects.all()[:2]

    SQL bruto

    Se você estiver curioso sobre o que o Django está fazendo nos bastidores, você pode inspecionar o SQL bruto:

     print(Contact.objects.all().query)

    Conclusão

    Django QuerySets são incrivelmente poderosos, e dominá-los é uma virada de jogo para trabalhar com dados em seus projetos. Não importa se você está filtrando registros, contando linhas ou realizando consultas complexas, QuerySets fornecem as ferramentas necessárias para fazer o trabalho de forma eficiente.

    Ao entender o básico e mergulhar em operações mais avançadas, você será capaz de escrever código limpo e otimizado que aproveita ao máximo o ORM do Django. Se você achou este guia útil, sinta-se à vontade para compartilhá-lo — pode ser o recurso que outra pessoa está procurando!

    Published: 3 weeks, 5 days ago.