Django
Entendendo Melhor
    Bruno Gama Catão
Templates
•   Alguns conceitos:
    •   Exibindo valores: {{variavel}}
    •   Estruturas de controle:
        •   {% if condicao %} {%else%} {%endif%}
        •   {% for expressão%} {%endfor%}
    •   Variáveix especial:
        •   {{forloop.counter}}
        •   {{forloop.revcounter}}
        •   {{forloop.first}}
        •   {{forloop.last}}
Templates
• {%ifequal valor1 valor2%} {%endifequal%}
• {%ifnotequal val1 val2%} {%endifnotequal%}
• Filtros:
 • {{valor|lower} {{valor|upper}}
 • {{nome|truncatewords: “30”}}
 • {{lista|first}} {{lista|last}} {{lista|length}}
 • {{data|date:”d/m/Y”}} - Exibe: 05/06/2010
 • {{hora|date:”f”}} - Exibe: 12:30
Como Django gera as
    páginas ?
Usuario    urls.py



          views.py      Templates

           index( )
          cadastro( )   Arquivos
            listar( )   Estáticos



                        Banco de
          models.py
                         Dados
Servindo Arquivos
       Estáticos
• Arquivos estáticos (ou de mídia):
 • css, js, imagens (jpg, gif, png, etc);
• Como fazer ?
 • Dizer qual o diretório em settings.py;
 • Ativar a aplicação “static serve” no
    arquivo urls.py.
Definindo o diretório
            de mídia
• No arquivo settings.py encontre as linhas onde estão a
  varíaveis MEDIA_ROOT e MEDIA_URL;
• Atribua um valor à variável MEDIA_ROOT com o
  caminho absoluto onde estão os seus arquivos
  estáticos:
  •   MEDIA_ROOT = 'C:/temp/media'

• Atribua um valor à variável MEDIA_URL com a URL
  que você quer usar para acessar os seus arquivos:
  •   MEDIA_URL = '/arquivos/'
Ativando o static serve

 • No arquivo urls.py adicione o seguinte import:
 •   from django.conf import settings


 • E a seguinte definição:
 •   (r'^arquivos/(?P<path>.*)$', 'django.views.static.serve',
     {'document_root': settings.MEDIA_ROOT}),


Atenção: Este padrão de URL deve obedecer o valor da variável MEDIA_URL
Testando
• Modifique a sua aplicação:
 • Defina um diretório de mídia;
 • Adicione alguns arquivos dentro;
• Inicie o servidor (de dentro do diretório onde está o
  arquivo manage.py do seu projeto):
  • python manage.py runserver
• Teste:
 • http://localhost:8000/arquivos/foto.jpg
Fazendo upload de
        arquivos
• Django possui dois tipos de dados que
  podem ser utilizados para manipular
  arquivos:
 • models.FileField;
 • models.ImageField.
Exemplo
 • Vamos supor que as nossas notícias agora
    tenham imagens:
class Noticia(models.Model):
    jornalista      = models.ForeignKey(Jornalista)
    categoria       = models.ForeignKey(Categoria)
    titulo          = models.CharField(max_length=200)
    texto           = models.TextField()
    data_publicacao = models.DateTimeField()
    foto            = models.ImageField(upload_to="fotos")

    def __unicode__(self):
        return self.titulo
Modificando o template
<html>
	 <head>
	 	 <title>{{noticia.titulo}}</title>
	 </head>
	 <body>
	 	 <p>{{noticia.categoria}}: {{noticia.jornalista}}</p>
	 	 <img src="/arquivos/{{noticia.foto}}"/>
	 	 <h1>{{noticia.titulo}}</h1>
	 	 <h2>{{noticia.texto}}</h2>
	 </body>
</html>
Testando

• Para testar apague o arquivo do banco de
  dados (meusite.db) e em seguida sincronize
  o banco de dados;
• Em seguida inicie o servidor:
 • python manage.py runserver
Por quê a separação ?
• Arquivos estáticos (mídia) e templates são
  separados por razões de segurança;
• Você pode até definir o TEMPLATE_DIRS e
  o MEDIA_ROOT para o mesmo diretório,
  porém, assim você estará permitindo que
  usuários consigam ver o conteúdo dos seus
  templates.
Formulários

• O nosso cliente pediu para que
  permitíssemos aos usuários do nosso site
  comentar as notícias;
• Para isto iremos criar uma nova entidade,
  Comentario, e vamos adicionar um
  formulário no detalhe da notícia.
Classe Comentario
• No arquivo models.py:
class Comentario(models.Model):
    noticia    = models.ForeignKey(Noticia)
    comentario = models.TextField()

    def __unicode__(self):
        return self.comentario
Modificando o template
...
	 	 <hr/>
	 	 <h3>Comente a nossa not&iacute;cia:</h3>
	 	 <form action="/noticias/comente/" method="GET">
	 	 	 <input type="hidden" name="noticia_id" value="{{noticia.id}}"/>
	 	 	 <p><textarea name="texto" rows="5" cols="40"/></p>
	 	 	 <p><input type="submit" value="Enviar"/></p>
	 	 </form>
	 	 <br/>
	 	 <ul>
	 	 {%for comentario in noticia.comentario_set.all%}
	 	 	 <li>{{comentario}}</li>
	 	 {%endfor%}
	 	 </ul>
	 </body>
</html>
Adicionando comentários
           views.py

def adicionaComentario(request):
    noticia = get_object_or_404(Noticia, pk=request.GET['noticia_id'])
    com = Comentario(comentario=request.GET['texto'], noticia=noticia)
    com.save()
    return detalhe(request, noticia.id)
Modificando o urls.py

(r'^comente/$', 'adicionaComentario'),
Testando


• Adicione alguns comentários às suas
  notícias e veja se está tudo correndo bem.
GET x POST
• Existem duas formas de passar parâmetros
  de um formulário HTML:
 • GET - Parâmetros passados através de
    URL;
 • POST - Parâmetros passados através de
    um fluxo de entrada e saída entre o
    navegador e o servidor.
GET x POST


• O método GET apresenta problemas de
  privacidade e tem uma limitação de até 256
  caracteres (limite do tamanho da URL).
Modificando o nosso
formulário para usar POST

• Django acrescenta algumas verificações de
  segurança para utilização de formulários
  POST;
• Isto evita que usuário maliciosos enviem
  dados indevidos para as nossas aplicações.
Modificando o template

<form action="/noticias/comente/" method="POST">
	 {% csrf_token %}
	 <input type="hidden" name="noticia_id" value="{{noticia.id}}"/>
	 <p><textarea name="texto" rows="5" cols="40"/></p>
	 <p><input type="submit" value="Enviar"/></p>
</form>
Modificando o views.py
from django.template import RequestContext

def detalhe(request, noticia_id):
    noticia = get_object_or_404(Noticia, pk=noticia_id)
    return render_to_response('noticias/detalhe.html', {'noticia': noticia},
                              context_instance=RequestContext(request))

def adicionaComentario(request):
    noticia = get_object_or_404(Noticia, pk=request.POST['noticia_id'])
    com = Comentario(comentario=request.POST['texto'], noticia=noticia);
    com.save()
    return detalhe(request, noticia.id)
Desafio

• Adicione os campos autor e data de
  publicação aos comentários;
• Exiba os comentários ordenados pela data
  de publicação em ordem inversa;
• Dica:
 •   models.DateTimeField(auto_now=True)
models.py

class Comentario(models.Model):
    noticia         = models.ForeignKey(Noticia)
    autor           = models.CharField(max_length=100)
    data_publicacao = models.DateTimeField(auto_now=True)
    comentario      = models.TextField()

    def __unicode__(self):
        return self.comentario
detalhe.html
...
<form action="/noticias/comente/" method="POST">
	 {% csrf_token %}
	 <input type="hidden" name="noticia_id" value="{{noticia.id}}"/>
	 <p>Autor: <input type="text" name="autor"/></p>
	 <p><textarea name="texto" rows="5" cols="40"/></p>
	 <p><input type="submit" value="Enviar"/></p>
</form>
<br/>
<ul>
{%for comentario in comentarios%}
	 <li>{{comentario.autor}} -
	     {{comentario.data_publicacao|date:"d/m/Y"}}:
	     {{comentario}}</li>
{%endfor%}
</ul>
...
views.py
def detalhe(request, noticia_id):
    noticia = get_object_or_404(Noticia, pk=noticia_id)
    comentarios = noticia.comentario_set.all().order_by('-data_publicacao')
    return render_to_response('noticias/detalhe.html',
                              {'noticia': noticia,
                               'comentarios' : comentarios},
                              context_instance=RequestContext(request))
Formatos de
          data e hora
• Visitem a página:
 • http://docs.djangoproject.com/en/dev/ref/
    templates/builtins/
• Procurem por Available format strings;
• Tem uma lista imensa de formatos de data
  e hora que podem ser utilizados.
Desafio

• Utilizem os conceitos aprendidos e implementem
  um blog;
• Dica:
 • http://pypi.python.org/pypi/django-tinymce/

Python 07

  • 1.
    Django Entendendo Melhor Bruno Gama Catão
  • 2.
    Templates • Alguns conceitos: • Exibindo valores: {{variavel}} • Estruturas de controle: • {% if condicao %} {%else%} {%endif%} • {% for expressão%} {%endfor%} • Variáveix especial: • {{forloop.counter}} • {{forloop.revcounter}} • {{forloop.first}} • {{forloop.last}}
  • 3.
    Templates • {%ifequal valor1valor2%} {%endifequal%} • {%ifnotequal val1 val2%} {%endifnotequal%} • Filtros: • {{valor|lower} {{valor|upper}} • {{nome|truncatewords: “30”}} • {{lista|first}} {{lista|last}} {{lista|length}} • {{data|date:”d/m/Y”}} - Exibe: 05/06/2010 • {{hora|date:”f”}} - Exibe: 12:30
  • 4.
    Como Django geraas páginas ?
  • 5.
    Usuario urls.py views.py Templates index( ) cadastro( ) Arquivos listar( ) Estáticos Banco de models.py Dados
  • 6.
    Servindo Arquivos Estáticos • Arquivos estáticos (ou de mídia): • css, js, imagens (jpg, gif, png, etc); • Como fazer ? • Dizer qual o diretório em settings.py; • Ativar a aplicação “static serve” no arquivo urls.py.
  • 7.
    Definindo o diretório de mídia • No arquivo settings.py encontre as linhas onde estão a varíaveis MEDIA_ROOT e MEDIA_URL; • Atribua um valor à variável MEDIA_ROOT com o caminho absoluto onde estão os seus arquivos estáticos: • MEDIA_ROOT = 'C:/temp/media' • Atribua um valor à variável MEDIA_URL com a URL que você quer usar para acessar os seus arquivos: • MEDIA_URL = '/arquivos/'
  • 8.
    Ativando o staticserve • No arquivo urls.py adicione o seguinte import: • from django.conf import settings • E a seguinte definição: • (r'^arquivos/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), Atenção: Este padrão de URL deve obedecer o valor da variável MEDIA_URL
  • 9.
    Testando • Modifique asua aplicação: • Defina um diretório de mídia; • Adicione alguns arquivos dentro; • Inicie o servidor (de dentro do diretório onde está o arquivo manage.py do seu projeto): • python manage.py runserver • Teste: • http://localhost:8000/arquivos/foto.jpg
  • 10.
    Fazendo upload de arquivos • Django possui dois tipos de dados que podem ser utilizados para manipular arquivos: • models.FileField; • models.ImageField.
  • 11.
    Exemplo • Vamossupor que as nossas notícias agora tenham imagens: class Noticia(models.Model): jornalista = models.ForeignKey(Jornalista) categoria = models.ForeignKey(Categoria) titulo = models.CharField(max_length=200) texto = models.TextField() data_publicacao = models.DateTimeField() foto = models.ImageField(upload_to="fotos") def __unicode__(self): return self.titulo
  • 12.
    Modificando o template <html> <head> <title>{{noticia.titulo}}</title> </head> <body> <p>{{noticia.categoria}}: {{noticia.jornalista}}</p> <img src="/arquivos/{{noticia.foto}}"/> <h1>{{noticia.titulo}}</h1> <h2>{{noticia.texto}}</h2> </body> </html>
  • 13.
    Testando • Para testarapague o arquivo do banco de dados (meusite.db) e em seguida sincronize o banco de dados; • Em seguida inicie o servidor: • python manage.py runserver
  • 14.
    Por quê aseparação ? • Arquivos estáticos (mídia) e templates são separados por razões de segurança; • Você pode até definir o TEMPLATE_DIRS e o MEDIA_ROOT para o mesmo diretório, porém, assim você estará permitindo que usuários consigam ver o conteúdo dos seus templates.
  • 15.
    Formulários • O nossocliente pediu para que permitíssemos aos usuários do nosso site comentar as notícias; • Para isto iremos criar uma nova entidade, Comentario, e vamos adicionar um formulário no detalhe da notícia.
  • 16.
    Classe Comentario • Noarquivo models.py: class Comentario(models.Model): noticia = models.ForeignKey(Noticia) comentario = models.TextField() def __unicode__(self): return self.comentario
  • 17.
    Modificando o template ... <hr/> <h3>Comente a nossa not&iacute;cia:</h3> <form action="/noticias/comente/" method="GET"> <input type="hidden" name="noticia_id" value="{{noticia.id}}"/> <p><textarea name="texto" rows="5" cols="40"/></p> <p><input type="submit" value="Enviar"/></p> </form> <br/> <ul> {%for comentario in noticia.comentario_set.all%} <li>{{comentario}}</li> {%endfor%} </ul> </body> </html>
  • 18.
    Adicionando comentários views.py def adicionaComentario(request): noticia = get_object_or_404(Noticia, pk=request.GET['noticia_id']) com = Comentario(comentario=request.GET['texto'], noticia=noticia) com.save() return detalhe(request, noticia.id)
  • 19.
  • 20.
    Testando • Adicione algunscomentários às suas notícias e veja se está tudo correndo bem.
  • 21.
    GET x POST •Existem duas formas de passar parâmetros de um formulário HTML: • GET - Parâmetros passados através de URL; • POST - Parâmetros passados através de um fluxo de entrada e saída entre o navegador e o servidor.
  • 22.
    GET x POST •O método GET apresenta problemas de privacidade e tem uma limitação de até 256 caracteres (limite do tamanho da URL).
  • 23.
    Modificando o nosso formuláriopara usar POST • Django acrescenta algumas verificações de segurança para utilização de formulários POST; • Isto evita que usuário maliciosos enviem dados indevidos para as nossas aplicações.
  • 24.
    Modificando o template <formaction="/noticias/comente/" method="POST"> {% csrf_token %} <input type="hidden" name="noticia_id" value="{{noticia.id}}"/> <p><textarea name="texto" rows="5" cols="40"/></p> <p><input type="submit" value="Enviar"/></p> </form>
  • 25.
    Modificando o views.py fromdjango.template import RequestContext def detalhe(request, noticia_id): noticia = get_object_or_404(Noticia, pk=noticia_id) return render_to_response('noticias/detalhe.html', {'noticia': noticia}, context_instance=RequestContext(request)) def adicionaComentario(request): noticia = get_object_or_404(Noticia, pk=request.POST['noticia_id']) com = Comentario(comentario=request.POST['texto'], noticia=noticia); com.save() return detalhe(request, noticia.id)
  • 26.
    Desafio • Adicione oscampos autor e data de publicação aos comentários; • Exiba os comentários ordenados pela data de publicação em ordem inversa; • Dica: • models.DateTimeField(auto_now=True)
  • 27.
    models.py class Comentario(models.Model): noticia = models.ForeignKey(Noticia) autor = models.CharField(max_length=100) data_publicacao = models.DateTimeField(auto_now=True) comentario = models.TextField() def __unicode__(self): return self.comentario
  • 28.
    detalhe.html ... <form action="/noticias/comente/" method="POST"> {% csrf_token %} <input type="hidden" name="noticia_id" value="{{noticia.id}}"/> <p>Autor: <input type="text" name="autor"/></p> <p><textarea name="texto" rows="5" cols="40"/></p> <p><input type="submit" value="Enviar"/></p> </form> <br/> <ul> {%for comentario in comentarios%} <li>{{comentario.autor}} - {{comentario.data_publicacao|date:"d/m/Y"}}: {{comentario}}</li> {%endfor%} </ul> ...
  • 29.
    views.py def detalhe(request, noticia_id): noticia = get_object_or_404(Noticia, pk=noticia_id) comentarios = noticia.comentario_set.all().order_by('-data_publicacao') return render_to_response('noticias/detalhe.html', {'noticia': noticia, 'comentarios' : comentarios}, context_instance=RequestContext(request))
  • 30.
    Formatos de data e hora • Visitem a página: • http://docs.djangoproject.com/en/dev/ref/ templates/builtins/ • Procurem por Available format strings; • Tem uma lista imensa de formatos de data e hora que podem ser utilizados.
  • 31.
    Desafio • Utilizem osconceitos aprendidos e implementem um blog; • Dica: • http://pypi.python.org/pypi/django-tinymce/