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/