Django 6.0 em 2026: Chaves Primárias Compostas, Tarefas em Background e Perguntas de Entrevista
Django 6.0 em 2026: chaves primárias compostas, tarefas em background, template partials, middleware CSP nativo e perguntas de entrevista técnica.

O Django 6.0 representa a maior evolução do framework Python para desenvolvimento web desde o lançamento da versão 4.0. Liberada em 2026, essa versão entrega funcionalidades que a comunidade Django solicitava há anos: chaves primárias compostas nativas no ORM, um sistema embutido de tarefas em background sem dependências externas, template partials para reaproveitamento de trechos HTML e um middleware de Content Security Policy integrado ao framework. O resultado prático é uma redução significativa na quantidade de pacotes de terceiros necessários para colocar uma aplicação Django em produção, além de uma arquitetura mais enxuta e padronizada.
O Django segue um ciclo de lançamento previsível: versões LTS (Long Term Support) a cada dois anos e versões intermediárias a cada oito meses. O Django 6.0 exige Python 3.12 ou superior. As chaves primárias compostas, que apareceram como funcionalidade estável no Django 5.2, estão completamente integradas ao ORM nesta versão. Já o sistema de tarefas em background e os template partials são novidades exclusivas do Django 6.0.
Chaves primárias compostas com CompositePrimaryKey
Bancos de dados relacionais utilizam chaves primárias compostas para identificar registros de forma única por meio da combinação de duas ou mais colunas. Até o Django 5.2, para modelar esse tipo de relação era necessário recorrer a alternativas como unique_together ou pacotes de terceiros. O campo CompositePrimaryKey resolve essa questão diretamente no ORM, eliminando a necessidade de um campo id autoincrementável em tabelas de junção.
O cenário mais comum envolve tabelas intermediárias em que a combinação de duas chaves estrangeiras forma a identidade única do registro. O exemplo abaixo modela um sistema de inventário onde cada produto em cada depósito possui uma quantidade associada:
# models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=100)
sku = models.CharField(max_length=20, unique=True)
class Warehouse(models.Model):
code = models.CharField(max_length=10, primary_key=True)
location = models.CharField(max_length=200)
class Inventory(models.Model):
pk = models.CompositePrimaryKey("product_id", "warehouse_id")
product = models.ForeignKey(Product, on_delete=models.CASCADE)
warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=0)
last_restocked = models.DateTimeField(auto_now=True)O campo pk recebe os nomes das colunas no banco de dados (e não os nomes dos campos do modelo Django). O framework gera uma constraint PRIMARY KEY (product_id, warehouse_id) diretamente no banco, garantindo unicidade sem precisar de um campo id artificial.
Consultando chaves compostas no ORM
A interação com o ORM continua com a mesma interface que qualquer desenvolvedor Django já conhece. A chave composta é representada como uma tupla Python, o que permite filtrar, criar e atribuir registros de maneira intuitiva:
# views.py
from .models import Inventory, Product, Warehouse
# Create records
laptop = Product.objects.create(name="Laptop Pro", sku="LP-001")
warehouse_a = Warehouse.objects.create(code="WH-A", location="Berlin")
item = Inventory.objects.create(
product=laptop,
warehouse=warehouse_a,
quantity=50
)
# Access the composite pk as a tuple
print(item.pk) # (1, "WH-A")
# Filter by composite pk
result = Inventory.objects.filter(pk=(1, "WH-A")).first()
# Assign a composite pk directly
new_item = Inventory(pk=(2, "WH-B"))
print(new_item.product_id) # 2
print(new_item.warehouse_id) # "WH-B"Essa funcionalidade é especialmente valiosa para equipes que trabalham com schemas legados de banco de dados ou que estão migrando de outros ORMs que já ofereciam suporte a chaves compostas. O Django Admin, os serializers do Django REST Framework e o sistema de migrations reconhecem automaticamente modelos com CompositePrimaryKey, sem necessidade de nenhuma configuração adicional.
Tarefas em background nativas com o decorator @task
Uma das adições mais aguardadas do Django 6.0 é o sistema de tarefas em background integrado ao framework. O módulo django.tasks disponibiliza um decorator @task e um método .enqueue() que permitem adiar a execução de funções sem precisar configurar um broker de mensagens externo ou workers separados.
O sistema foi projetado para operações que não devem travar o ciclo de request-response HTTP: envio de e-mails, geração de relatórios, processamento de uploads e chamadas a APIs externas. A definição de tarefas segue a convenção do Django de manter um módulo tasks.py dentro de cada app:
# tasks.py
from django.tasks import task
from django.core.mail import send_mail
@task
def send_welcome_email(user_email, username):
"""Send a welcome email after user registration."""
send_mail(
subject="Welcome to the platform",
message=f"Hello {username}, your account is ready.",
from_email=None, # uses DEFAULT_FROM_EMAIL
recipient_list=[user_email],
)
return f"Email sent to {user_email}"
@task
def generate_report(report_id, format="pdf"):
"""Generate an export report asynchronously."""
from .services import ReportService
report = ReportService.generate(report_id, format=format)
return report.file_pathO disparo de tarefas a partir de uma view utiliza o método .enqueue(), que serializa os argumentos e os envia para o backend configurado para execução assíncrona:
# views.py
from .tasks import send_welcome_email, generate_report
def register_user(request):
# ... user creation logic ...
# Enqueue the task for background execution
send_welcome_email.enqueue(
user_email=user.email,
username=user.username
)
return redirect("dashboard")
def export_view(request, report_id):
generate_report.enqueue(report_id=report_id, format="csv")
return JsonResponse({"status": "processing"})O Django 6.0 inclui um backend de banco de dados como opção padrão e um backend Redis para cenários com maior volume de tarefas. A configuração no settings.py permite escolher o backend e ajustar parâmetros como número de workers e intervalo de polling.
A distinção de escopo é fundamental para tomar a decisão correta. As tarefas nativas do Django 6.0 atendem de forma eficiente casos de uso simples a moderados. Para cenários que exigem roteamento avançado de filas, workflows complexos (chains, chords), retentativas com backoff exponencial configurável ou processamento distribuído em várias máquinas, o Celery continua sendo a ferramenta mais adequada.
Template partials: fragmentos reutilizáveis no sistema de templates
O sistema de templates do Django ganha uma funcionalidade que desenvolvedores acostumados com frameworks frontend já conhecem: a possibilidade de definir fragmentos reutilizáveis dentro de um mesmo arquivo e referenciá-los de forma seletiva. As tags {% partialdef %} e {% partial %} permitem agrupar vários componentes visuais em um único template e consumir apenas o fragmento desejado.
O exemplo a seguir define duas representações de um produto -- um card para catálogo e uma linha para tabelas de inventário -- dentro do mesmo arquivo:
<!-- templates/components/cards.html -->
{% partialdef product_card %}
<div class="card">
<h3>{{ product.name }}</h3>
<p class="price">{{ product.price|floatformat:2 }} EUR</p>
<span class="stock {% if product.in_stock %}available{% else %}sold-out{% endif %}">
{% if product.in_stock %}In Stock{% else %}Sold Out{% endif %}
</span>
</div>
{% endpartialdef %}
{% partialdef product_row %}
<tr>
<td>{{ product.name }}</td>
<td>{{ product.price|floatformat:2 }} EUR</td>
<td>{{ product.quantity }}</td>
</tr>
{% endpartialdef %}A inclusão seletiva de um partial utiliza a sintaxe de fragmento #nome na tag {% include %}:
<!-- templates/shop/catalog.html -->
{% extends "base.html" %}
{% block content %}
<div class="product-grid">
{% for product in products %}
{% include "components/cards.html#product_card" %}
{% endfor %}
</div>
{% endblock %}A principal vantagem é a redução de arquivos espalhados pelo projeto. Antes dos template partials, cada variação visual de um componente precisava de seu próprio arquivo de template. Agora, variações relacionadas convivem no mesmo arquivo, facilitando a manutenção e a navegação do código. Essa funcionalidade se integra naturalmente com HTMX e outros padrões de troca parcial de HTML, onde o servidor precisa devolver trechos específicos de uma página sem renderizar o template completo.
Pronto para mandar bem nas entrevistas de Django?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Middleware CSP nativo para Content Security Policy
A proteção contra ataques de cross-site scripting (XSS) e injeção de conteúdo depende de cabeçalhos Content Security Policy bem configurados. O Django 6.0 incorpora um middleware dedicado e um módulo django.utils.csp que torna desnecessária a dependência de pacotes como django-csp.
A configuração é definida no settings.py por meio de um dicionário que mapeia diretivas CSP para seus valores permitidos:
# settings.py
from django.utils.csp import CSP
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.middleware.security.ContentSecurityPolicyMiddleware",
# ... other middleware
]
SECURE_CSP = {
"default-src": [CSP.SELF],
"script-src": [CSP.SELF, CSP.NONCE],
"style-src": [CSP.SELF, "https://fonts.googleapis.com"],
"img-src": [CSP.SELF, "https:", "data:"],
"font-src": [CSP.SELF, "https://fonts.gstatic.com"],
"connect-src": [CSP.SELF],
}
# Report-only mode for testing (does not block, only reports violations)
SECURE_CSP_REPORT_ONLY = {
"default-src": [CSP.SELF],
"report-uri": ["/csp-report/"],
}A constante CSP.NONCE gera automaticamente um nonce único por requisição e injeta o valor nas tags <script> do template. Isso permite executar scripts inline legítimos enquanto bloqueia qualquer script injetado por um atacante. O modo SECURE_CSP_REPORT_ONLY é particularmente útil na fase de implantação: registra as violações sem bloquear nenhum recurso, permitindo ajustar as políticas aos poucos antes de ativar o modo de bloqueio definitivo.
A integração nativa garante compatibilidade com o sistema de templates do Django, incluindo a geração automática de atributos nonce nos blocos {% static %} e nos scripts inline do painel administrativo.
Outras mudanças relevantes no Django 6.0
Além das funcionalidades principais, o Django 6.0 traz melhorias que impactam o dia a dia do desenvolvimento.
BigAutoField como campo padrão: DEFAULT_AUTO_FIELD agora aponta para BigAutoField em projetos novos, eliminando o limite de 2,1 bilhões de registros que o AutoField impunha. Projetos existentes que não configuraram esse valor de forma explícita vão receber um aviso durante a execução das migrations.
Paginação assíncrona: Os QuerySet paginados agora suportam métodos assíncronos como await page.ahas_next() e await page.ahas_previous(). Isso permite que views assíncronas realizem paginação sem bloquear o event loop, melhorando o throughput em aplicações rodando com ASGI.
Auto-imports no shell: O comando python manage.py shell agora importa automaticamente todos os models do projeto e os módulos mais utilizados (django.db.models, django.utils.timezone, datetime). Essa melhoria acaba com a necessidade de digitar os mesmos imports toda vez que se abre uma sessão interativa de depuração.
API moderna de e-mail: O módulo django.core.mail passa a ter suporte nativo para anexos inline, headers personalizados e uma interface fluente que simplifica a composição de e-mails complexos sem precisar manipular objetos MIME diretamente.
Perguntas de entrevista sobre Django 6.0 para 2026
As entrevistas técnicas para vagas backend com Python em 2026 já incluem perguntas sobre as funcionalidades do Django 6.0. As questões abaixo cobrem os temas com maior probabilidade de aparecer em um processo seletivo focado em Django.
P: Qual a diferença entre unique_together e CompositePrimaryKey?
unique_together cria uma constraint de unicidade sobre um conjunto de colunas, mas o model continua com seu campo id autoincrementável como chave primária. CompositePrimaryKey elimina o campo id e define a combinação de colunas como a chave primária real no banco de dados. A primeira é uma restrição adicional; a segunda redefine a identidade do registro.
P: Quando vale a pena usar as tarefas nativas do Django 6.0 em vez do Celery?
O sistema nativo atende bem tarefas simples que não exigem roteamento de filas, retentativas sofisticadas nem workflows do tipo canvas (chains, groups, chords). O Celery se faz necessário quando a aplicação precisa de processamento distribuído em várias máquinas, agendamento periódico avançado (Celery Beat) ou monitoramento em tempo real com ferramentas como Flower.
P: Como se acessa a chave primária composta no ORM?
A propriedade pk de uma instância com CompositePrimaryKey retorna uma tupla Python com os valores das colunas que formam a chave. É possível filtrar com Model.objects.filter(pk=(valor1, valor2)) e atribuir com instancia = Model(pk=(valor1, valor2)). O ORM desempacota a tupla automaticamente nos campos correspondentes.
P: Que vantagem os template partials oferecem em relação a vários arquivos de include?
Os template partials permitem definir vários fragmentos reutilizáveis em um único arquivo, reduzindo a proliferação de arquivos pequenos e facilitando a navegação do código. A sintaxe {% include "arquivo.html#nome" %} referencia de forma seletiva um fragmento específico, o que se integra naturalmente com padrões de troca parcial de HTML como HTMX.
Conclusão
O Django 6.0 consolida a posição do framework como a solução mais completa do ecossistema Python para desenvolvimento web em 2026. Os destaques desta versão podem ser resumidos nos seguintes pontos:
- Chaves primárias compostas eliminam a necessidade de campos
idartificiais em tabelas intermediárias, alinhando o ORM do Django com o modelo relacional padrão dos bancos de dados - Tarefas nativas em background reduzem a complexidade operacional para operações assíncronas simples, dispensando a configuração de broker e workers externos
- Template partials organizam fragmentos reutilizáveis dentro de um mesmo arquivo, diminuindo a proliferação de templates e facilitando a integração com padrões como HTMX
- Middleware CSP nativo oferece proteção contra XSS com geração automática de nonces e modo report-only para implantações graduais
- BigAutoField como padrão previne o esgotamento de chaves primárias em tabelas de alto volume sem necessidade de configuração extra
- Paginação assíncrona e auto-imports no shell melhoram a produtividade no dia a dia, tanto em código de produção quanto em sessões de depuração
- O Django 6.0 exige Python 3.12+ e é compatível com os principais bancos de dados suportados (PostgreSQL, MySQL, SQLite, Oracle)
Comece a praticar!
Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.
Tags
Compartilhar
Artigos relacionados

Django e Celery: Processamento Assíncrono de Tarefas e Perguntas de Entrevista 2026
Guia completo de Django e Celery com configuração, filas, Celery Beat, deploy em produção e perguntas de entrevista técnica para desenvolvedores Python em 2026.

Django 5.2: Middleware Personalizado e Tratamento de Signals para Entrevistas Técnicas
Guia completo sobre middleware personalizado e signals no Django 5.2. Implementação de middleware de logging, middleware assíncrono, signals pre_save/post_save e perguntas frequentes de entrevista.

Django ORM: otimize as consultas para o máximo desempenho
Guia completo de otimização de consultas no ORM do Django. select_related, prefetch_related, índices, análise do problema N+1 e técnicas avançadas para aplicações de alto desempenho.