Por Luferat em 04/11/2026
Vamos usar esse banco de dados no site? Inicialmente, vamos listar "todas as postagens" na página inicial, mas apenas os campos id, thumbnail, title e summary.
O caminho mais simples é buscar todos os posts na view com Post.objects.all() e percorrer a lista no template com {% for in %}.
Edite blog/views/home.py:
from django.shortcuts import render
from blog.models import Post
def home(request):
# Obtém todos os `post`
posts = Post.objects.all()
# Passa as postagens para o template via `context`
context = {
'ownername': 'Joca da Silva',
'posts': posts,
}
return render(request, 'home.html', context)
Edite blog/templates/home.html:
Só o block content muda, o block aside, por enquanto, continua igual.
{% block content %}
<section>
<h2>Página inicial</h2>
{# Loop para iterar cada postagem #}
{% for post in posts %}
<div>
<img src="{{ post.thumbnail }}" alt="{{ post.title }}">
<h3><a href="#{{ post.id }}">{{ post.title }}</a></h3>
<p>{{ post.summary }}</p>
<small>Post nº {{ post.id }}</small>
</div>
{% empty %}
{# `empty` acontece quando o iterable `post` está vazio #}
<p>Nenhum post cadastrado ainda.</p>
{% endfor %}
</section>
{% endblock %}
Pontos importantes:
O Post.objects.all() retorna um QuerySet, e o Django só vai ao banco quando o template começa a percorrer a lista.
Por enquanto não tem filtro nem ordenação, então a ordem não é garantida.
O {% empty %} é executado quando a lista está vazia, assim a página não fica em branco se não houver posts.
O campo id existe automaticamente em todo model (chave primária criada pelo Django), mesmo sem estar declarado no models.py. Por isso o {{ post.id }} funciona.
Como a view está em blog/views/home.py (um pacote), confirme que existe um blog/views/__init__.py.
O import from blog.models import Post funciona por caminho absoluto, mas se preferir caminho relativo seria from ..models import Post (dois pontos, por estarmos uma pasta abaixo).
Para testar, rode o servidor e abra a página inicial.
Sei que está "feio"! Vai melhorar. Por hora, foque na lógica!
Vamos melhorar essa listagem:
Obter as postagens ordenadas pela data (created_at) mais recente;
Obter apenas as postagens com is_active = True e is_deleted = False.
Na view, vamos trocar Post.objects.all() por Post.objects.filter() e aplicar os filtros como argumento, em seguida, order_by() para ordenar.
Edite blog/views/home.py novamente para:
from django.shortcuts import render
from blog.models import Post
def home(request):
# Obtém todos os `post` usando filtros e ordenamento
posts = Post.objects.filter(
is_active=True
).order_by('-created_at') # Ordenados pela data mais recente
return render(
request,
'home.html',
{
'posts': posts,
'total_posts': posts.count(),
'show_aside': False,
}
)
Destaques:
O template home.html não precisa de alteração;
Vários argumentos dentro do mesmo filter() são combinados com a lógica AND;
O sinal de menos em -created_at inverte a ordem: do mais recente para o mais antigo. Sem o sinal, a ordem seria crescente;
A ordem dos métodos (filter antes de order_by ou o contrário) não muda o resultado, porque o Django monta uma única consulta SQL só quando o QuerySet é percorrido.
Se você sempre quiser essa ordenação em qualquer consulta de Post, dá para definir no Meta do model:
class Meta:
verbose_name = 'Post'
verbose_name_plural = 'Posts'
ordering = ['-created_at']
Dessa forma, .order_by('-created_at') na view deixa de ser necessário. Isso gera uma nova migração (makemigrations e migrate), mas não altera a tabela no banco. Como vamos usar ordens diferentes em outras páginas, manter o order_by explícito na view é uma escolha válida.
Para testar, no Django Admin, desmarque “Ativo” em um post, marque “Excluído” em outro e crie um novo. Ao recarregar a página inicial, os dois primeiros devem sumir e o mais novo deve aparecer no topo.
Teste bastante!