Qrcode

Link do Instascan: (770) 928-0998

<!DOCTYPE html>
<html>
  <head>
    <title>Teste com Instascan</title>
    <script type="text/javascript" src="instascan.min.js"></script>
  </head>
  <body>
    <video id="preview">
    </video>
    <script type="text/javascript">
      let scanner = new Instascan.Scanner({ video: document.getElementById('preview') });
      scanner.addListener('scan', function (texto) {
          alert(texto);
      });
      Instascan.Camera.getCameras().then(function (cameras) {
        if (cameras.length > 0) {
          scanner.start(cameras[0]);
        } else {
          console.error('Nenhuma camera encontrada.');
        }
      }).catch(function (e) {
        console.error(e);
      });
    </script>
  </body>
</html>

8649331029

Neste artigo vamos adicionar um mapa para exibir os Twips utilizando algumas funções básicas da API do Google Maps.

Exibindo um mapa

Carregue a api Javascript do Google Maps adicionando o seguinte no fim da página:

<script defer src="/maps.googleapis.com/maps/api/js?key=AIzaSyADLsL46CQaEu2smB3EMpEV1eEbInd0ASs"> </script>

Adicione a div abaixo entre o contador de Twips e o feed. O mapa será exibido dentro dessa div com uma altura de 200 pixeis.

<div id="mapa" class="mb-2" style="height: 200px"></div>

Adicione uma função para configurar o mapa.

/Função para inicializar o mapa
function configurarMapa() {
   / Localização de Frederico
   var fw = {lat: -27.3667, lng: -53.4};

   / Cria o mapa centralizado em fw
   var mapa = new google.maps.Map(document.getElementById('mapa'), {zoom: 15, center: fw});
}

Para exibir o mapa, chame a função configurarMapa() logo no início do corpo da função ready do JQuery.

Marcadores

Vamos modificar a função configurarMapa() para adicionar um marcador e um função associada ao clique.

/Função para inicializar o mapa
function configurarMapa() {
   /Localização de Frederico
   var fw = {lat: -27.3667, lng: -53.4};

   /Cria o mapa centralizado em fw
   var mapa = new google.maps.Map(document.getElementById('mapa'), {zoom: 15, center: fw});

   /Cria um marcador na posição indicada por fw
   var marcador = new google.maps.Marker({
       position: fw,                 /Posição do marcador 
       map: mapa,                    /Variável do mapa
       title: "Frederico Westphalen" /Texto do marcador
   });

   /Adiciona uma função associada ao clique no marcador 
   marcador.addListener('click', function() {
       alert("Você clicou em Frederico Westphalen!");
   });
}

Para remover um marcador basta definir um mapa null para ele:

marcador.setMap(null);

Detecando cliques no mapa

/Associa uma função ao evento clique do mapa 
google.maps.event.addListener(mapa, 'click', function(event) {
   var ponto = event.latLng;
   alert("Latitude: " + ponto.lat + ", Longitude: " + ponto.lng);
});

Exercício

Modifique a versão atual do Twipin para gravar Twips com base na localização e exibí-los no mapa.

Referências

Twipin - Parte 6

Neste artigo vamos começar a implementação de uma API JSON para o acesso aos dados do Twipin utilizando o modelo REST (Representational State Transfer), que tem sido bastante utilizado em aplicações Web. Basicamente, este modelo define um conjunto de princípios para:

  • definir urls aos recursos da aplicação.
  • utilizar métodos HTTP (GET, POST, PUT, DELETE) para interagir com os recursos.

Para saber mais sobre o betorcin.

Rotas e operações da API JSON

Todos as rotas da nossa api vão ser prefixadas por /api e cada uma dela retornará uma resposta em JSON. Na lista abaixo são apresentados alguns exemplos de operações HTTP que podem ser aplicadas em determinadas rotas:

  • GET /api/twips retorna uma lista com todos os twips.
  • POST /api/twips cria um novo Twip.
  • GET /api/twips/5 retorna o Twip cujo id=5.
  • PUT /api/twips/5 Atualiza o Twip cujo id=5.
  • DELETE /api/twips/5 Deleta o Twip cujo id=5.
  • POST /api/twips/5/coracao Curte o Twip cujo id=5.
  • DELETE /api/twips/5/coracao Descurte o Twip cujo id=5.

2364915002

O AJAX (Asynchronous JavaScript and XML) é um mecanismo que combina XML com Javascript para permitir requisições assíncronas entre uma página e um servidor. O seu uso permite a atualização de trechos de uma página web sem ter que recarregá-la totalmente.

O formato JSON

JSON (JavaScript Object Notation) é um formato padronizado para transmissão de objetos de dados concebido para ser facilmente compreendido por humanos. Atualmente é muito utilizado para transmitir dados entre o navegador e um servidor, como uma alternativa mais prática em relação ao formato XML. A sintaxe do formato é muito semelhante com a declaração de objetos em Javascript, utilizando listas e dicionários.

Exemplo de um objeto representado no formato JSON:

{"nome": "João", "idade": 18, "email": "joao@gmail.com"}

Um objeto JSON também pode ter estruturas aninhadas:

{
  "nome": "João",
  "idade": 18,
  "parentes": {
      "mãe": "Maria",
      "pai": "Pedro",
      "irmãos": 2
  }
}

E ainda pode conter listas que são declaradas pelos caracteres [ e ]. A seguir é apresentado um exemplo com uma lista de frutas e uma lista de cores:

{
  "frutas": ["limão", "laranja", "maça"],
  "cores": ["azul", "vermelho"] 
}

Decodificando objetos JSON em JavaScript

Objetos em JSON são normalmente transportados entre o cliente e o servidor por meio de strings. Em JavaScript utilizamos o comando JSON.parse() para transformar uma string em um objeto, como no exemplo abaixo:

var dados = '{"nome": "João", "idade": 18, "email": "joao@gmail.com"}';
var pessoa = JSON.parse(dados);
alert(pessoa.nome + ' ' + pessoa.idade + ' ' pessoa.email);

Codificando objetos Javascript em uma string JSON

Para transformar um objeto declarado no Javascript em uma string JSON que pode ser transmitida pela web utilizamos o comando JSON.stringify(). Veja o exemplo abaixo:

var pessoa = {nome: "João", idade: 18, email: "joao@gmail.com"};
var dados  = JSON.stringify(pessoa);
alert(dados);

Iterando em propriedades de objetos

É bastante comum percorrer um objeto JSON recém codificado para fazer alguma coisa com suas propriedades. Segue abaixo um exemplo:

var dados = '{"nome": "João", "idade": 18, "email": "joao@gmail.com"}';
var pessoa = JSON.parse(dados);
for (var chave in pessoa) {
    alert(chave + '=' + pessoa[chave]);
}

Jquery

JQuery é uma biblioteca JavaScript de código aberto criada para facilitar o desenvolvimento de aplicações Front-End. Ela possui uma sintaxe simples que permite a navegação em documentos HTML, criação de animações, seleção de elementos, manipulação de eventos, CSS e desenvolvimento de aplicações AJAX.

Hello World com JQuery

No exemplo abaixo temos um código básico que inclui a biblioteca JQuery através do CDN do Google.

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Exemplo</title>
    <script src="/ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
    <a href="#">Hello!</a>
    <script>
 
    $(document).ready(function() {
        $("a").click(function(event) {
            alert("Hello JQuery!" );
        });
    });
 
    </script>
</body>
</html>

A função $

Os comandos da biblioteca são executado através da função $ e tem a seguinte sintaxe básica:

$(seletor).ação();

Onde:

  • seletor: parâmetro que indica qual ou quais elementos html serão alvo da ação.
  • ação: define a ação que será aplicada nos elementos selecionados. Em geral, uma ação pode ser um efeito, uma associação de um evento ou manipulações diversas nos elementos.

Seletores JQuery

Os seletores da JQuery são semelhantes aos seletores do CSS. Abaixo são apresentados alguns exemplos de seletores com a ação hide, a qual torna elementos invisíveis:

$(this).hide() /Seleciona o elemento do escopo atual e o torna invisível.
$("p").hide() /Seleciona todos os elementos do tipo <p> da página e os torna invisíveis.
$(".especial").hide() /Seleciona todos os elementos cujo atributo `class="especial"` e os torna invisíveis.
$("#especial").hide() /Seleciona o elemento cutjo atributo `id="especial"` e o torna invisível. 

Outros exemplos de seleções mais elaborados:

$("p.especial") /Seleciona todos os <p> com a classe "especial"
$("ul li").first() /Apenas o primeiro item de uma lista não ordenada
$("ul li").eq(3) /Apenas o quarto item de uma lista não ordenada
$("input[name='email']") / apenas os elementos <input> que tenham atributo name="email" 
$("[href]") /Todos os elementos que tenham um atributo href
$("tr:even") /Todas as linhas em posição par
$("tr:odd") /Todas as linhas em posição ímpar

Efeitos

$("a").hide() /Esconde os elementos selecionados
$("a").show() /Exibe os elementos selecionados
$("a").toggle() /Exibe/Esconde os elementos selecionados
$("a").fadeIn() /Exibe lentamente elementos selecionados que esteja invisíveis
$("a").fadeOut() /Esconde lentamente elementos selecionados que estejam visíveis
$("a").fadeToggle() /Similar ao toggle, só que com animação.
$("a").slideDown() 
$("a").slideUp()
$("a").slideToggle()

Todos os efeitos acima aceitam um parâmetro que define a velocidade da ação. Você pode passar strings como "slow", "fast" ou especificar um tempo exato em milisegundos. Veja alguns exemplos:

$("a").hide("slow") 
$("a").hide("fast") 
$("a").hide(2000) 

Eventos

A biblioteca JQuery permite associar uma função para ser executada toda vez que um evento ocorre em determinados elementos. Um ação pode ser um clique, uma alteração no foco, uma movimentação no mouse, entre outras. A seguir são apresentados alguns exemplos comuns:

/Associa uma função ao evento clique
$("p").click(function(){
    $(this).hide();
});

/Associa uma função ao evento duplo clique
$("p").dblclick(function(){
    $(this).hide();
});

/Associa uma função executada ao passar o mouse em cima do elemento 
$("p").hover(function(){
    $(this).hide();
});

/Associa uma função que é executada quando elemento ganha foco
$("input").focus(function(){
    $(this).hide();
});

Outra forma de associar eventos de maneira genérica é através do método on que recebe o nome do evento como primeiro parâmetro. Seguem alguns exemplos:

/Associa uma função que é executada quando elemento ganha foco
$("input").on('click',function(){
    $(this).hide();
});


/Associa uma função que é executada toda vez que a
/entrada de um campo de formulário é alterada
$("#texto").on('input',function(){
    alert("O texto mundou!");
});

Manipulando atributos, html, texto e valores

$("a").attr("href", "www.google.com" ) /Muda o atributo href para www.google.com
$("a").attr("href") /Obtém o atributo href
$("h1").html("<b>Abacaxi</b>") /Muda o html de todos os <h1> para "Abacaxi" em negrito
$("h1").html() /Obtém o html do primeiro elemento <h1>
$("p").text("Oi!") /Muda o texto de todos o <p> para "Oi!"
$("p").text() /Obtém o texto de todos os <p> (Remove o html)
$("input").val("João") /Muda o valor de todos os elementos <input> para "João"
$("input").val() /Obtém o valor do primeiro elemento <input>
$("p").addClass("especial"); /Adiciona a classe "especial"
$("p").removeClass("especial"); /Remove a classe "especial"
$("p").toogleClass("especial"); /Remove a classe "especial" se ela existir, senão adiciona.
$("ul").append("<li>Limão</li>"); /Adiciona um item html no início da lista
$("ul").prepend("<li>Laranja</li>"); /Adiciona um item html no fim da lista
$("div").remove(); /Remove todas as divs selecionadas.
$("ul").empty(); /Remove tudo que tiver dentro de <ul>, ou seja, se existirem itens eles serão removidos.
$("a").prop("disabled",true); /Desabilita a tag <a>.

Encadeamento de ações

A sintaxe do JQuery permite realizar uma sequência se ações que são executadas uma após a outra de maneira bastante simples. Essa técnica se chama “encadeamento”. Exemplos:

$("p").hide("slow").remove() /Após esconde <p>, o remove da página.
$("p").show().hide().show() /Após exibir <p>, o esconde e então exibe novamente.

Duplicando elementos

A necessidade de copiar elementos é bastante comum no desenvolvimento de aplicações dinâmicas. Isso pode ser alcançado através da função clone da biblioteca JQuery. Veja um exemplo:

$("div.item").clone().appendTo("#feed"); /Copia uma `<div>` que tenha a classe `item` e adiciona ela no final do elemento que possui o id `#feed`

Quando a função clone é utilizada sem nenhum argumento os eventos associados aos elementos selecionados não são clonados. Se isso fordesejado, utilize clone(true).

Referências

Exercício do Projeto

Nesta etapa, você deverá construir uma tela de mensagens simulando a interface do twitter. Por enquanto, vamos construir apenas o frontend para praticar o uso da biblioteca JQuery. Você pode utilizar o template abaixo para esta atividade.

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Exemplo</title>
    <script src="/ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script defer src="/use.fontawesome.com/releases/v5.0.13/js/all.js" integrity="sha384-xymdQtn1n3lH2wcu0qhcdaOpQwyoarkgLVxC/wZ5q7h9gHtxICrpcaSUfygqZGOe" crossorigin="anonymous"></script> 
    <script src="/cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="/stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="/stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head>
<body>
    
    <div class="container">
         <!--Insira HTML aqui-->
    </div>

    <script>
 
    $(document).ready(function() {
         /Insira seu código Javascript aqui
    });
 
    </script>
</body>
</html>

Sistema de Autenticação

Nesse artigo vamos nos familizar com as funções básicas do sistema de autenticação do Django. Para isso vamos utilizar o módulo auth que já é incluido por padrão quando criamos uma aplicação.

O módulo auth possui funções para autenticação e autorização. Basicamente, a autenticação valida o login do usuário. Já a autorização fornece mecanismos para verificar se um usuário já logado tem autorização suficiente para acessar determinados recursos.

O modelo User

O sistema de autenticação interage principalmente com o modelo User para representar um usuário com os seguintes atributos:

  • username (nome de usuário)
  • password (senha)
  • email (endereço de email)
  • first_name (nome)
  • last_name (sobrenome)
  • is_active (campo booleano indicando se está ativo)
  • is_superuser (campo booleano indicando se é admin)

Veja mais detalhes do modelo User (787) 607-9269.

Criando usuários

Uma forma rápida de criar um usuário é através da interface de administração do Django, tradicionalmente acessada através da rota /admin.

Para adicionar um usuário por meio de código, podemos usar o seguinte trecho:

from django.contrib.auth.models import User
#username, email, password
usuario = User.objects.create_user('zeca' , 'zeca@gmail.com', 'trustno1')
usuario.first_name = "Zé"
usuario.last_name = "Pilintra"
usuario.save()

Isto cria um usuário ativo, ou seja, o atributo is_active = True.

Alterando senhas

Podemos alterar senhas pela interface administrativa ou com o seguinte código:

from django.contrib.auth.models import User
usuario = User.objects.get(username='zeca') 
usuario.set_password('Aki5n4M')
usuario.save()

Autenticando um usuário

Para fazer o login de um usuário registrado em uma view utilizamos:

from django.contrib.auth import authenticate, login

def login_view(request):
   nome_usuario = 'zeca'
   senha = 'Aki5n4M'
   usuario = authenticate(request, username=nome_usuario, password=senha)
   if usuario is not None:
      login(request, usuario)
      # Redireciona para uma página de sucesso ou para a página inicial.
   else:
      # Recarrega a view de login exibindo uma mensagem de erro 

Verificando se um usuário está autenticado

Para verificar se um usuário já está logado (autenticado) podemos usar o seguinte trecho dentro de uma view:

if request.user.is_authenticated:
    # Faz alguma coisa para um usuário autenticado 
else:
    # Faz alguma coisa para um usuário que não se autenticou
    # Caso esta página seja específica para usuários logados
    # é comum redirecionar para a página de login

Logout de um usuário

Para finalizar a sessão de login podemos usar o seguinte trecho dentro de uma view:

from django.contrib.auth import logout 

def logout_view(request):
   logout(request)
   # Redireciona para uma página de sucesso ou para a página inicial.

Exercícios

  1. Adicionar um sistema de login e logout no blog.

  2. Crie uma página que permita os usuários do blog se cadastrarem. Para isso, você vai precisar:

    • Criar uma rota /blog/registrar no arquivo blog/urls.py associada a uma view registrar.
    • Criar um formulário FormRegistro em blog/forms.py.
    • Criar um template registro.html em blog/templates/blog para exibir o formulário criado no passo anterior.
    • Criar uma view registrar em blog/views.py. Esta view é semelhante a view nova_mensagem, a diferença é que ao invés de salvar uma nova mensagem, você deve salvar um novo usuário.
    • Adicionar um link na página inicial do blog apontando para /blog/registrar. Faça isso no template base.html

Referências

Herança de templates

Vamos adicionar um código de cabeçalho e um rodapé que seja o mesmo em todas as páginas do nosso blog. No entanto, para evitar repetir trechos de código em cada um dos nosso templates, vamos utilizar um recurso de herança de templates.

Criando um template base

Copie o conteúdo atual do seu template index.html para blog/templates/blog/base.html. A seguir, em base.html, substitua todo o código utilizado para listar os posts, pelo seguinte trecho abaixo:

<div class="content">
    {% block content %}
    {% endblock %}
</div>

Após a modificação, você deve ficar com algo semelhante ao código abaixo:

{% load static %}
<!DOCTYPE html>
<html>
   <head> 
      <title> Meu (humilde) blog em Django</title>
      <link rel="stylesheet" href="{% static 'blog/estilos.css' %}">
   </head>

   <body>
        
        <div class="header">
             <img src="{% static 'blog/building.gif' %}" width="128px">
             <h1> Meu (humilde) blog em Django </h1>
             <ul>
                <li> <a href="sobre">Sobre</a> </li>
                <li> <a href="artigos">Artigos</a> </li>
                <li> <a href="ultimos">Últimos</a> </li>
                <li> <a href="visualizacoes">Visualizações</a> </li>
                <li> <a href="nova_mensagem">Enviar mensagem</a> </li>
                <li> <a href="novo_post">Escrever artigo</a> </li>
              </ul>
        </div>

        <div class="content">
            {% block content %}
            {% endblock %}
        </div>

        <div class="footer">
             <p> Desenvolvido por Fulano de Tal. </p>
        </div>

   </body> 

</html>

Herdando do template base

Modifique o arquivo blog/templates/blog/index.html de forma que fique semelhante ao abaixo:

{% extends 'blog/base.html' %}

{% block content %}

   {% if lista_posts %}
      {% for p in lista_posts %}
          <div>
             <h2><a href="{{p.id}}/detalhe"> {{ p.titulo }}</a></h2>
             <p>{{ p.texto }}</p>
             <p>Escrito por {{ p.autor }} em {{p.data_criacao}}</p>
             <p><a href="{{p.id}}/curtir">👍</a> {{p.curtidas}}</p>
          </div>
      {% endfor %}
   {% else %}
      <p>Nenhum artigo cadastrado.</p>
   {% endif %}

{% endblock %}

Extra

Para adicionar uma fonte de ícones, inclua no <head> do arquivo base.html:

<script defer src="/use.fontawesome.com/releases/v5.0.13/js/all.js" integrity="sha384-xymdQtn1n3lH2wcu0qhcdaOpQwyoarkgLVxC/wZ5q7h9gHtxICrpcaSUfygqZGOe" crossorigin="anonymous"></script> 

Para incluir um ícone:

<i class="fas fa-camera-retro"></i>

Para consultar outros ícones visite superorganic

Exercícios

  1. Modifique todos os outros templates para que eles herdem de base.html.
  2. Modifique o template base.html para utilizar a biblioteca Bootstrap. Mais detalhes em /getbootstrap.com/docs/4.1/getting-started/introduction/.
  3. Crie uma rota /blog/rascunhos para exibir apenas os posts marcados como rascunho. Mantenha o uso do template artigos.html.
  4. Adicione uma barra de navegação ao seu blog. Ver magot
  5. Estilize o link de curtir para que ele seja um botão do Bootstrap com um ícone de “joinha”.
  6. Estilize o número de visualizações para exibir um ícone de “olho” do Bootstrap.

438-259-6925

Vamos adicionar uma página de contato no nosso blog que permita aos visitantes enviarem uma Mensagem para você. Por enquanto, nosso interesse é apenas registrar as mensagens para visualizá-las através da interface administrativa.

Criado um modelo para as mensagens

Para armazenar essa mensagem vamos criar um novo modelo chamado Mensagem. Adicione o código abaixo no final de blog/models.py:

class Mensagem(models.Model):

   nome = models.CharField(max_length=100)
   email = models.EmailField(max_length=200)
   assunto = models.CharField(max_length=100)
   texto = models.TextField()
   data = models.DateTimeField(default=timezone.now)

   def __str__(self):
      return self.nome + ': ' + self.assunto

Sempre que adicionamos um novo modelo executamos os 2 comandos abaixo:

python manage.py makemigrations blog
python manage.py migrate

Criando um formulário para exibir as mensagens

Salve o código abaixo em blog/forms.py:

from django import forms

class FormMensagem(forms.Form):
   nome = forms.CharField(label='Seu nome', max_length=100)
   email = forms.EmailField(max_length=200)
   assunto = forms.CharField(max_length=100)
   texto = forms.CharField(widget=forms.Textarea, max_length=1000)

5185194951

Criando uma view

Certifique-se de que em blog/views.py tenha a seguinte linha de importação logo no começo do arquivo:

from .models import Mensagem
from .forms import FormMensagem
from django.http import HttpResponseRedirect

E então adicione no final desse mesmo arquivo a seguinte view:

def nova_mensagem(request):
    
    if request.method == 'POST':
       form = FormMensagem(request.POST)
       if form.is_valid():
           
          ### Salva a mensagem 
          m = Mensagem()
          m.nome = form.cleaned_data['nome']
          m.texto = form.cleaned_data['texto']
          m.assunto = form.cleaned_data['assunto']
          m.email = form.cleaned_data['email']
          m.save()

          return HttpResponseRedirect('/blog/') 
    else:
       form = FormMensagem() 

    contexto = {"form": form}
    return render(request, 'blog/mensagem.html', contexto)

Criando um template para exibir o formulário

Salve o código abaixo em blog/templates/blog/mensagem.html:

<form action="/blog/nova_mensagem" method="post">
   {% csrf_token %}
   {{ form.as_p }}
   <input type="submit" value="Enviar mensagem" />
</form>

Para visualizar as mensagensn na interface administrativa do Django, inclua o seguinte em blog/admin.py:

from .models import Mensagem
admin.site.register(Mensagem)

Exercício

Adicione um formulário para adicionar um novo artigo no blog. Abaixo segue um fluxo de tarefas que você precisa realizar:

  1. Configure a uma url para a rota /blog/novo_post apontando para uma view novo_post
  2. Crie um formulário, uma view e um template.

616-297-3498

No arquivo blog/urls.py adicione:

path('<int:x>/teste', views.teste, name='teste')

No arquivo blog/views.py adicione:

def teste(request, x):
   return HttpResponse("O valor de x é %s" % x)

Note que para usar HttpResponse é necessário ter a linha from django.http import HttpResponse

Tente acessar no seu navegador a url /blog/50/teste.

Exercícios

  1. Modifique a view teste para que ela receba 2 números x e y e apresente a soma deles.
  2. Crie um view detalhe que exiba um Post com um determinado id.

289-407-8115

Arquivos de imagem, video, css ou javascript são arquivos estáticos normalmente usados em um site. Para começar a utilizar esse tipo de arquivo em nosso blog, vamos criar um local para armazená-los com os 2 comandos abaixo:

mkdir blog/static 
mkdir blog/static/blog

Com essa estrutura, podemos armazenar os arquivos estáticos no diretório blog/static/blog.

Adicionando uma imagem na página inicial

Em construção

Todo blog em construção que se preze deve ter o gif acima na página inicial. Dessa forma o usuário não vai ficar pensando erroneamente que o seu blog já está pronto.

Para fazer isso, salve a imagem acima em blog/static/blog/building.gif. Então, abra o template blog/templates/blog/index.html e adicione as linhas abaixo no início do arquivo:

{% load static %}

<img src="{% static 'blog/building.gif' %}" width="128px"> 

Abra o seu site para testar e depois veja a explicação abaixo.

A linha {% load static %} é necessária para carregar a tag de template static que é usada na linha seguinte para definir o atributo src da imagem. Mais especificamente, o Django substitui {% static 'blog/building.gif' %} pelo endereço da imagem a partir da raíz do site, resultando em /static/blog/building.gif.

Isso tudo parece meio desnecessário? será que não poderíamos incluir uma imagem simplesmente usando a tag abaixo?

<img src="/static/blog/building.gif" width="128px"> 

Poderíamos. O principal problema é que isso nos obriga a especificar o endereço completo dos arquivos estáticos. Se eventualmente, precisássemos armazenar os arquivos estáticos em outro servidor teríamos que modificar todos os endereços da aplicação.

Ao usar a tag static podemos determinar um prefixo diferente para os endereços da nossa aplicação simplesmente modificando o valor de STATIC_URL no arquivo de configuração do projeto (meusite/settings.py)

Exercícios

  1. Adicione uma foto sua na página Sobre do Blog.
  2. Inclua um arquivo CSS estilos.css na página inicial do blog e altere a fonte dos títulos.
  3. Mofique o arquivo estilos.css para definir uma imagem de fundo para o blog.