Neste post vamos ver como deixar as nossas views dinâmicas inserindo dados do banco, ou seja inserir dados do model para o template.

Django model para o template

Opa, tudo certo? Antes de começarmos queria avisar que este post faz parte de uma sequência onde estamos desbravando todos os recursos do Django, se você quiser acompanhar todo o projeto veja os posts anteriores.

Posts anteriores e repositório:

Caso você chegou direto neste post, esta é a sexta parte do tutorial, confira o resto da série:

  1. Instalando Django 2 e criando um projeto;
  2. Criando rotas e views;
  3. Introdução aos templates do Django;
  4. Adicionado Bootstrap ao projeto;
  5. Criando um model e entendendo migrations;

Para quem quer clonar o projeto ou dar um fork clique aqui!

Criando a URL da view do post e app_name:

Primeiramente vamos adicionar um novo conceito aqui de app_name, para não termos a chance de haver uma URL duplicada.

O Django nos da uma maneira de nomear o app e assim as URLs se tornam únicas.

Abra o arquivo urls.py da aplicação blog e deixe-o assim:

from django.urls import path
from . import views
app_name = 'blog'

urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('<slug:slug>', views.post_detail, name='post_detail'),
    path('sobre-nos/', views.about, name='about'),
    path('contato/', views.contact, name='contact'),
]

A primeira novidade é o app_name, com esse recurso teremos URLs únicas de certeza, desse modo devemos mudar a chamada das URLs na view para este novo recurso funcionar, você já verá como.

Por fim adicionamos também a URL das views dos posts.

Estas funcionarão da seguinte maneira: a slug formará a URL da view, assim sendo temos mais chances de não termos posts duplicados.

Há melhores maneiras de definir isso, porém mais complexas, então num post futuro pretendo dar um upgrade nesta parte.

Por fim selecionamos a view post_detail que iremos criar, e o nome desta como post_detail também.

Agora que temos um nome de aplicativo definido para o blog, e a url das views, vamos fazer a pequena alteração que falei antes para a aplicação funcionar.

Abra o arquivo base.html e nos hrefs que contiverem URLs ligadas ao blog, aplique o blog: antes delas, conforme abaixo:

<a class="navbar-brand" href="{% url 'blog:post_list' %}">Blog</a>

Você deve fazer na página de sobre nós e contato e também na lista de artigos onde chamamos a url post_detail.

Esse blog: que irá nos dar a exclusividade de URLs para o app blog, e caso você ficou com dúvida: agora toda URL que nos redirecione para outra página do app blog precisa conter o ‘blog:’ antes o do nome da view.

Templates estáticos para dinâmicos:

Agora que já temos posts cadastrados no banco, podemos inseri-los nas views, vamos fazer isso agora.

Primeiramente devemos passar os dados para nosso arquivo de views, e ele depois retornará estes dados para o template, então em blog abra o arquivo views.py, e faça as alterações:

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from .models import Post

def post_list(request):
    posts = Post.objects.all().order_by('-created_at')
    return render(request, 'blog/post_list.html', {'posts':posts})

Primeiramente importamos o model que queremos os dados, no caso Post.

Depois utilizamos um comando da ORM do Django, que pega todos os posts e ordena por data de criação.

Por fim encaminhamos todos os posts encontrados para a view.

obs: Note que também importamos o get_object_or_404 que irá nos ajudar a resgatar um post do banco de dados futuramente, ou caso não encontrado entregar uma página 404.

Agora abra a view que lista os posts, que é post_list.html, e vamos remover os cards e adicionar uma template tag de for, veja:

{% extends 'blog/base.html' %}
{% block title %}Listagem de Posts{% endblock %}

{% block content %}
    <div class="container">
        <div class="jumbotron jumbotron-fluid">
          <div class="container">
            <h1 class="display-4">Bem vindo ao Django blog!</h1>
            <p class="lead">Aqui você vai encontrar os melhores posts sobre o framework.</p>
          </div>
        </div>
        <div class="row">
                {% for post in posts %}
            <div class="col">
              <div class="card" style="width: 18rem;">
                <img class="card-img-top" src="https://via.placeholder.com/286x180" alt="Card image cap">
                <div class="card-body">
                  <h5 class="card-title">{{ post.title }}</h5>
                            <p class="card-text">{{ post.body|truncatechars:50 }}...</p>
                            <p>Criado em {{ post.created_at }} por {{ post.author }}</p>
                  <a href="{% url 'blog:post_detail' post.slug %}" class="btn btn-primary">Ver o post completo</a>
                </div>
              </div>
                </div>
                {% endfor %}
        </div>
    </div> 
{% endblock %}

 

Agora veja como ficou a página inicial:

E também de brinde ganhamos vários termos novos no código, template tags e um for, vamos ver o que cada um faz:

  • {% for %}{% endfor %}: um laço de repetição, igual ao das outras linguagens, vai fazer um loop entre os elementos que escolhermos, neste caso são os posts, atente-se para sempre fechar os blocos;
  • {{ post.* }}: essa template tag simboliza o post com todos os seus atributos únicos, então selecionamos vários deles para dispor ao longo do template, lembrando que os posts vieram la da função da nossa View;

Criando a view do post:

Primeiramente devemos criar a view post_detail no nosso arquivo views.py, insira ela abaixo de post_list da seguinte maneira:

def post_detail(request, slug):
    post = get_object_or_404(Post, slug=slug)
    return render(request, 'blog/post_detail.html', {'post':post})

Aqui há duas novidades:

  • slug como parâmetro: nós vamos encontrar o post no banco de dados pelo slug;
  • get_object_or_404: caso o Django não encontre o post pelo slug,ele entregará uma página 404;

O resto segue normal, entregamos para o template o objeto do post com todos os seus dados.

Falta ainda o template da view do post, para isso vamos criar um arquivo chamado post_detail.html em blog/templates/blog, veja como deve ser a estrutura:

{% extends 'blog/base.html' %}
{% block title %}{{ post.title }}{% endblock %}

{% block content %}
    <div class="container">
        <h1>{{ post.title }}</h1>
        <p>Publicado em {{ post.created_at }} por {{ post.author }}</p>
        <p>{{ post.body|linebreaks }}</p>
    </div> 
{% endblock %}

 Aqui não há nada de diferente que já não vimos antes, utilizamos nosso template de base.html, mudamos o bloco title e content para conter os dados do post.

Pronto, agora entendemos a ideia de como obter objetos do banco pela view e inserir num template.

Conclusão:

Primeiramente inserimos o conceito de app_name, que consegue distinguir as urls de todos os aplicativos e assim não precisamos nos preocupar com nomes únicos.

Agora há a possibilidade de ter duas urls com mesmo nome em apps distintos.

Criamos também as urls de lista e post view, na de post view inserimos um conceito novo de argumento para a url, que no caso é o slug, a url da view será formada pelo slug do post.

Depois disso e por fim, criamos os templates para estas duas urls, assim concretizando o ciclo do Django de Model View Template.

Confira também o nosso canal do Youtube com muito conteúdo sobre programação, clicando aqui.

Pessoal, agradeço a todos por lerem até o fim, se possível compartilhem com os amigos interessados em tecnologia e se inscrevam na nossa lista de e-mail para não perder as novidades.

Caso haja alguma dúvida ou crítica, comentem abaixo que responderei assim que possível, obrigado!

 

Subscribe
Notify of
guest

0 Comentários
Inline Feedbacks
View all comments