• Sistemas Web
  • Criando templates

Parte 6: Criando templates#

A nossa vida como desenvolvedores de softwares sempre será muito mais fácil se mantivermos as responsabilidades dos artefatos que criamos separadas. Em outras palavras, cada artefato com uma responsabilidade bem definida.

Por isso que o nosso objetivo nesta parte do handout é fazer uso de templates para que possamos separar algumas das funcionalidades que até o momento estão todas codificadas dentro do arquivo views.py.

Exercise 1

Crie as pastas notes/templates/notes (sim, o notes é repetido mesmo) e então crie os dois arquivos a seguir

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Get-it</title>
  </head>

  <body>
    {% block content %} {% endblock %}
  </body>
</html>
{% extends "notes/base.html" %}

{% block content %}
<img src="notes/img/logo-getit.png">
<p>Como o Post-it, mas com outro verbo</p>

<form method="post">
  <label for="titulo">Título</label>
  <input id="titulo" type="text" name="titulo" />
  <label for="detalhes">Detalhes</label>
  <textarea id="detalhes" name="detalhes"></textarea>
  <input type="submit" />
</form>

<ul>
  <li>Nenhuma anotação por enquanto.</li>
</ul>
{% endblock %}

Mas por que dois arquivos? Para que eles servem?

Provavelmente nós teremos mais do que uma página no nosso projeto. Por isso, criamos o arquivo base.html com o código HTML que vai se repetir em todas as páginas. No index.html nós usamos o {% extends "notes/base.html" %} para indicar para a engine de template do Django que nós queremos usar o base.html como base. Então modificamos apenas os blocos necessários. O que está entre o {% block content %} e {% endblock %} no index.html substituirá esse mesmo bloco no base.html. Você pode dar o nome que quiser para os seus blocos.

Ok, mas como eu uso isso?#

Vamos lá!

Exercise 2

Modifique o seu arquivo notes/views.py substituindo o seu conteúdo por:

from django.shortcuts import render

def index(request):
    return render(request, 'notes/index.html')

A função render recebe um request e o nome de um arquivo de template e carrega o seu conteúdo.

Teste sua página.

A página ainda não está nada elegante, mas já deve mostrar o conteúdo. Ou pelo menos parte dele. Além do HTML gerado pelo servidor, aplicações web normalmente precisam servir outros arquivos – como imagens, JavaScript, ou CSS – necessário para renderizar a página web completa. No Django, nós chamamos estes arquivos de “arquivos estáticos”.

Para projetos pequenos isto não é tão relevante porque você pode manter os arquivos estáticos em qualquer lugar do seu servidor web. No entanto, em projetos grandes - especialmente aqueles compontos por múltiplas aplicações - trabalhar com múltiplos conjuntos de arquivos estáticos pode ser complicado.

É para isto que o django.contrib.staticfiles serve: ele coleciona os arquivos estáticos de cada uma de suas aplicações (e qualquer outro lugar que você especifique) em um único local que pode ser facilmente servido em produção.

Exercise 3

Crie as pastas notes/static/notes/img e salve esta imagem em notes/static/notes/img/logo-getit.png.

Exercise 4

Modifique o arquivo notes/templates/notes/index.html com o seguinte conteúdo:

{% extends "notes/base.html" %}
{% load static %}

{% block content %}
<img src="{% static 'notes/img/logo-getit.png' %}" width="100" height="60"/>
<p>Como o Post-it, mas com outro verbo</p>

<form method="post">
  <label for="titulo">Título</label>
  <input id="titulo" type="text" name="titulo" />
  <label for="detalhes">Detalhes</label>
  <textarea id="detalhes" name="detalhes"></textarea>
  <input type="submit" />
</form>

<ul>
  <li>Nenhuma anotação por enquanto.</li>
</ul>
{% endblock %}

Nessas linhas nós indicamos para a engine de template do Django que queremos usar a template tag static (template tags são as tags entre {%%}) e depois a utilizamos para carregar o caminho completo do arquivo estático notes/img/logo-getit.png.

Agora sim, a imagem deve ser carregada.

Se a imagem não carregar

Se você fez as modificações pedidas no exercício e a imagem não carregar, tente parar a execução do servidor e inicializar novamente.

Outros arquivos estáticos

Assim como acabamos de fazer com a imagem, você pode adicionar outros arquivos estáticos (css, javascript, etc.) na pasta notes/static/notes e eles serão disponibilizados pelo servidor. Para manter a organização, você pode criar uma pasta notes/static/notes/css para colocar os arquivos css, um notes/static/notes/script para os arquivos javascript, e assim por diante.

A imagem foi, mas e as anotações no banco de dados?#

Esse é o nosso próximo passo! Sabemos que as anotações que criamos manualmente pelo Django Admin estão armazenadas no banco de dados, mas como fazemos para acessá-las e depois passar para o template?

O template do Django é capaz de executar um código parecido com Python e inclusive pode receber algumas variáveis! Vamos resolver primeiro o problema de como carregar os dados do banco de dados.

Exercise 5

Faça as seguintes modificações no arquivo notes/views.py:

from django.shortcuts import render
from .models import Note


def index(request):
    all_notes = Note.objects.all()
    print(all_notes)
    return render(request, 'notes/index.html', {'notes': all_notes})

Nós estamos importando o modelo Note e carregando todas as entradas dessa tabela. O template recebe um dicionário que define as variáveis que estarão disponíveis para ele (chamamos esse dicionário de contexto).

O Manager objects

O atributo objects é um objeto do tipo Manager criado pelo Django. Ele possui diversos métodos que permitem interagir com o banco de dados. O all() lista todas as entradas, mas existem outros métodos bastante úteis, como o filter() e o get().

Exercise 6

Modifique o conteúdo da tag <ul> no arquivo index.html para:

<ul>
  <li>{{notes}}</li>
</ul>

Ele deve mostrar algo estranho como: <QuerySet [<Note: 1. Receita de miojo>, <Note: 2. Pão doce>, <Note: 3. Sorvete com cristais de leite>]>

Esse é o mesmo objeto que estava guardado na variável all_notes e foi passado para o contexto do template!

Exercise 7

Legal, mas está feio. Vamos deixar a página menos feia. Para isso, precisamos de uma forma de percorrer essas anotações e mostrar cada uma em uma <li> diferente. Modifique novamente o conteúdo da tag <ul> para:

`html <ul> {% for note in notes %} <li>{{ note.title }}</li> {% endfor %} </ul>

Agora sim!

O template tag {% for %}{% endfor %} funciona de forma muito parecida com o for do Python. O seu conteúdo é executado para cada elemento na lista fornecida. Uma das principais diferenças é a necessidade do {% endfor %} ao final. Isso acontece porque no HTML as indentações não podem ser utilizadas para definir blocos como no Python.

Quando queremos mostrar o valor de uma variável no HTML (equivalente ao que fazíamos com o .format()) devemos utilizar o {{}}.

Importante

Muitas coisas aconteceram nesse último exercício. Pare por um instante para refletir e garantir que entendeu o que está acontecendo nele.

Exercise 8

Modifique seu projeto para que o conteúdo das anotações também seja mostrado.

Acabou? Vamos para a próxima parte!