• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Django Módulo Básico Parte II
 

Django Módulo Básico Parte II

on

  • 4,363 views

Continuação da parte I, agora melhoramos nosso CMS, inserimos URL de busca, desenvolvemos uma URL para contato

Continuação da parte I, agora melhoramos nosso CMS, inserimos URL de busca, desenvolvemos uma URL para contato

Statistics

Views

Total Views
4,363
Views on SlideShare
4,363
Embed Views
0

Actions

Likes
1
Downloads
299
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Django Módulo Básico Parte II Django Módulo Básico Parte II Document Transcript

    • Django Módulo Básico Desenvolvendo uma aplicação WEB usando o framework DJANGO (parte II) Antonio Sérgio Nogueira 2010
    • Sumário 1.Sofisticando seu CMS...........................................................................................3 2.Adicionando um Editor de Rich-Text..................................................................3 3.Adicionando um sistema de busca.......................................................................5 4.Melhorando o sistema de busca............................................................................8 5.Cuidados com a segurança quando usamos um sistema de busca..................10 6. Desenvolvendo uma URL para contato............................................................10
    • 1. Sofisticando seu CMS – no último capítulo, da parte I deste documento, disponibilizamos um sistema de gerenciamento de conteúdo, através das aplicações contrib, projetadas para adicionar características que diminuem a quantidade de código. Nesta ocasião citamos o admin e mostramos as páginas planas (flatpages). As flatpages são bastantes simples e vamos customizá-las utilizando um editor rich- text no admin. 2. Adicionando um editor de Rich-Text (formato de arquivo de documento desenvolvido e de propriedade da Microsoft desde 1987 para intercâmbio de documentos entre diversas plataformas ) - as aplicações que usam flatpages já possuem qualidade, mas você pode adicionar um pouco mais de qualidade a estas aplicações (nos sites desenvolvidos com Django normalmente a página “About page” é uma flatpage), sem ter que digitar um texto HTML. Existem vários editores rich-text em Javascript, mas aqui nós usaremos um chamado TinyMCE, que é bastante popular e é o que tem um suporte melhor para navegadores. Além disso é software livre e você pode baixar uma cópia dele em http://tinymce.moxiecode.com/ , descompacte o pacote e dentro do pacote você encontrará um diretório jscripts/tiny_mce. Agora anote o diretório onde você colocou o arquivo e copie a pasta /tiny_mce para o diretório /meu_site/foto/js. No meu caso o diretório onde serão armazenados os arquivos estáticos é o diretório /meu_site/foto e depois edite o arquivo urls.py de seu projeto. Modifique o arquivo urls.py para que fique como abaixo ( atenção o path do document_root deve ser o caminho que está em seu micro): from django.conf.urls.defaults import * from meu_site.views import * from django.conf import settings # Uncomment the next two lines to enable the admin: from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Example: # (r'^meu_site/', include('meu_site.foo.urls')), # Uncomment the admin/doc line below and add 'django.contrib.admindocs' # to INSTALLED_APPS to enable admin documentation: #(r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: (r'^admin/(.*)', admin.site.root), #(r'^admin/',include('django.contrib.admin')), (r'^livros/$','meu_site.livros.views.lista_livros'),
    • (r'^foto/(.*)$', 'django.views.static.serve', {'document_root':settings.MEDIA_ROOT}), (r'^tiny_mce/(?P<path>.*)$', 'django.views.static.serve', { 'document_root': '/../../foto/js/tiny_mce/tiny_mce.js' }), (r'',include('django.contrib.flatpages.urls')), ) No arquivo settings.py coloque esta linha com o endereço da mídia, para que o software localize o arquivos de mídia. #settings.py # Absolute path to the directory that holds media. # Example: "/home/media/media.lawrence.com/" MEDIA_ROOT = os.path.join(PROJECT_ROOT_PATH,'foto').replace('','/') Recomendação: O uso do Django para servir arquivos estáticos terá impacto negativo na sua aplicação, por isso ao colocar o software em produção veja as especificações do Django para que o servidor de aplicação faça esse serviço. Nós adicionamos ao nosso site uma chamada de JavaScript para usarmos com as nossas páginas planas. Agora nós necessitamos de um modelo(template) que será usado para edição e adição das páginas planas. Por default, a aplicação admin buscará pela template em vários locais, e usará o primeiro que encontrar. Os nomes de template, por ordem de busca, que serão procurados são: 1. admin/flatpages/flatpage/change_form.html 2. admin/flatpages/change_form.html 3. admin/change_form.html Após encontrar a template o Django usará ela para adição e edição de todas as páginas que não forem fornecida a template, usando uma lista de templates o Django permite que você sobreponha a interface para uma aplicação específica. Agora vamos criar um diretório em templates “admin/flatpages/flatpage e dentro dele vamos colocar um arquivo chamado change_form.html. Este arquivo encontra-se em django/ contrib/admin/templates/admin/change_form.html(diretório onde está instalado o Django). Agora vamos abrir o arquivo e alterá-lo para que tenhamos acesso ao JavaScript do TinyMCE. Este arquivo é bastante complexo podendo ser adaptado para qualquer modelo de dados. A mudança que faremos é a seguinte: – Localize a linha 6 e veja que nela temos: {{ media }} – Adicione abaixo dela: <script type="text/javascript" src="/../../foto/js/tiny_mce/tiny_mce.js"> </script> <script type="text/javascript"> tinyMCE.init({
    • mode: "textareas", theme: "advanced" }); </script> Veja que você fará uso da URL que você definiu para servir os arquivos TinyMCE. Após salvar a modificação volte ao navegador e acesse as páginas planas e veja que existe um editor TinyMCE, que pode ser customizado, agregado a página de conteúdo. Outros editores(RTE -Rich Text Editor) também podem ser agregados desta mesma maneira. 3. Adicionando um sistema de busca – agora desenvolveremos nossas aplicações em Python e adicionaremos esta característica ao Django. Vamos desenvolver um sistema de busca independente que pode ser usado para consultar e retornar uma lista de páginas que contenham o assunto procurado. Digite o comando: python manage.py startapp busca. Um diretório de projeto foi criado:
    • /busca __init__.py → este arquivo indica que o diretório é um módulo Python views.py → contém as funções de controle que respondem ao HTTP models.py → contém os modelos de dados da aplicação Agora vamos importar os módulos necessários para desenvolver nossa vista(não se esqueça que a view é onde armazenamos o módulo de controle, modelo MVC). #views.py # classe que retorna a resposta no formato HTTP adequado p/ servidor from django.http import HttpResponse # módulo loader, funções para trabalhar as templates (diretório especificado em # TEMPLATE_DIRS) # Context classe usada para representar variáveis das templates from django.template import loader, Context # FlatPage é um modelo de classe que representa as páginas CMS from django.contrib.flatpages.models import FlatPage # define a função Python, com request uma instância de django.http.HttpRequest def busca(request): # busca uma variável q. O Django analisa ela e resulta uma HttpRequest com # como http://www.example.com/busca?q=oquevcquer # o atributo GET é um dicionário com o nome q e o valor oquevcquer query = request.GET['q'] # quase todas as classes Django possuem um atributo objects # que pode ser usado para busca no modelo, neste caso filtrado através do #método filters nas flatpages, com argumento content_icontains results = FlatPage.objects.filter(content__icontains=query) #com a busca e seu resultado produzimos o HTML e anexamos o conteúdo da # busca e retornamos a resposta com o HTML final processado template = loader.get_template('busca/busca.html') context = Context({ 'query': query, 'results': results }) response = template.render(context) return HttpResponse(response) Vamos criar o template busca.html no subdiretório templates/busca do meu_site e dentro dele armazenamos o arquivo. Busca.html <html> <head> <title>Busca</title>
    • </head> <body> <p>Você procura por:"{{ query }}"; o resultado está abaixo.</p> <ul> {% for page in results %} <li><a href="{{ page.get_absolute_url }}">{{ page.title }}</a></li> {% endfor %} </ul> </body> </html> Note que o arquivo faz uso das variáveis passadas para ele (query e results) veja que o arquivo usa as variáveis entre dois parantêses, é a forma de mostrar diretamente o resultado da variável. Nós também estamos usando as tags do template for e endfor para fazer um loop e mostrar todos os resultados obtidos. Veja também que temos dentro do loop {{page.title}} o campo título e o método {{page.get_absolute_url}} que retorna o URL usado para referenciar o objeto, isto faz parte do modelo FlatPage . Abra o arquivo urls.py e digite a linha abaixo depois da linha TinyMCE e antes da linha que captura todos os padrões das páginas planas. from django.conf.urls.defaults import * from meu_site.views import * from django.conf import settings #from meu_site.livros.views import * # Uncomment the next two lines to enable the admin: from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Example: # (r'^meu_site/', include('meu_site.foo.urls')), # Uncomment the admin/doc line below and add 'django.contrib.admindocs' # to INSTALLED_APPS to enable admin documentation: #(r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: (r'^admin/(.*)', admin.site.root), #(r'^admin/',include('django.contrib.admin')), (r'^livros/$','meu_site.livros.views.lista_livros'), (r'^foto/(.*)$', 'django.views.static.serve', {'document_root':settings.MEDIA_ROOT}), (r'^tiny_mce/(?P<path>.*)$', 'django.views.static.serve', { 'document_root': '/../../foto/js/tiny_mce/tiny_mce.js' }),
    • (r'^busca/$', 'meu_site.busca.views.busca'), (r'',include('django.contrib.flatpages.urls')), ) Use a seguinte URL para testar as buscas, substitua sss pela palavra que procura: http://localhost:8080/busca/?q=sss . Este arquivo views.py abaixo quando você digitar apenas http://localhost:8080/busca/ não dá erro porque você definiu através do get um valor default para a variável q, o que não ocorre com o anterior. # Create your views here. from django.http import HttpResponse from django.template import loader, Context from django.contrib.flatpages.models import FlatPage def busca(request): query = request.GET.get('q', " ") results = FlatPage.objects.filter(content__icontains=query) template = loader.get_template('busca/busca.html') context = Context({ 'query': query, 'results': results }) response = template.render(context) return HttpResponse(response) 4. Melhorando o sistema de busca – agora colocaremos um formulário para entrada dos dados e reduziremos a busca usando uma função chamada shorcuts que reduz todo esse trabalho, fazendo a carga da template, processando a saida e criando a resposta num único comando. Edite seu arquivo views.py no diretório de busca e deixe ele com o formato abaixo. from django.shortcuts import render_to_response from django.contrib.flatpages.models import FlatPage def busca(request): query = request.GET.get('q', ' ') results = [ ] if query: results = FlatPage.objects.filter(content__icontains=query) return render_to_response('busca/busca.html', { 'query': query, 'results': results }) Teste o sistema que ele funciona perfeitamente. Agora vamos modificar o template busca.html em /templates/busca.
    • busca.html <html> <head> <title>Busca</title> </head> <body> <form method="get" action="/search/"> <p><label for="id_q">Busca:</label> <input type="text" name="q" id="id_q" value="{{ query }}" /> <input type="submit" value="Executa" /></p> </form> {% if results %} <p>Você procura por:"{{ query }}"; o resultado está listado abaixo.</p> <ul> {% for page in results %} <li><a href="{{ page.get_absolute_url }}">{{ page.title }}</a></li> {% endfor %} </ul> {% else %} {% if query %} <p>Não encontrei nenhum resultado.</p> {% else %} <p>Digite a busca na caixa abaixo e pressione "Executa" para buscar.</p> {% endif %} {% endif %} </body> </html> Agora você irá executar a URL http://localhost:8080/busca/ e veja o que ocorre: Este é o resultado que aparece em meu micro onde já cadastrei algumas flatpages.
    • 5. Cuidados com a segurança quando usamos um sistema de busca - as aplicações web possuem uma vulnerabilidade do sistema de segurança que é o Cross- site scripting(XSS), este ataque ocorre quando injetam scripts maliciosos, no lado do cliente, em páginas web vistas por outros usuários. Através de um XSS, o hacker injeta códigos JavaScript em um campo texto que ao ser apresentado executa o script malicioso podendo causar muitos danos. Isto pode ser evitado pelo servidor se ele remover caracteres que formam as tags HTML. Uma outra forma de ataque é a chamada injeção SQL, onde o hacker usa uma entrada de usuário para fazer uma consulta ao banco de dados, por exemplo o hacker pode enviar o texto DROP DATABASE, que se cegamente executado pode apagar o banco. Para estes ataques o Django possui em primeiro lugar templates que automaticamente “escapam”(modificam o conteúdo) o conteúdo de variáveis evitando assim que elas sejam um código HTML executado pelo navegador, em segundo lugar ao usar models o Django constrói consultas ao banco de dados de forma que a injeção não é possível. Toda vez que você está lidando com os dados apresentados pelo usuário, você precisa de cuidado e garantia que você está tomando as medidas adequadas para preservar a segurança do seu site. 6.Desenvolvendo uma URL para contato – em primeiro lugar vamos desenvolver uma aplicação independente de contato. Digite no seu console: python manage.py startapp contato. Não devemos esquecer que o nosso OS é o Windows e estamos com o python e o django instalados e que o nosso diretório de trabalho é /meu_site, onde criamos nossa aplicação. A partir do momento que digitamos o comando um novo subdiretório foi criado com o nome contato, e que agora iremos alterar os arquivos para gerar a aplicação. Ao criar um formulário para contato devemos ter em mente que ele deve ser claro e útil e você deve validar os campos necessários de forma a evitar erros. Se ao enviar o formulário o mesmo contiver erros devemos mostrar os dados e avisar onde o erro ocorre evitando uma nova digitação das partes desnecessárias. O Django fará a maioria do trabalho necessário desde que você forneça a descrição do campo, as regras de validação e um simples template. 6.1 Criando o formulário de contato – o contato é uma forma de você conseguir aumentar a audiência de seu site , vamos então começar digitando no arquivo de URL(urls.py) a linha: (r'^contato/$', 'meu_site.contato.views.contato'), ….. (r'^livros/$','meu_site.livros.views.lista_livros'), (r'^contato/$','meu_site.contato.views.contato'), (r'^foto/(.*)$', 'django.views.static.serve', {'document_root':settings.MEDIA_ROOT}), (r'^tiny_mce/(?P<path>.*)$', 'django.views.static.serve', { 'document_root': '/../../foto/js/tiny_mce/tiny_mce.js' }),
    • (r'^busca/$', 'meu_site.busca.views.busca'), (r'',include('django.contrib.flatpages.urls')), ) O formulário Django é criado da mesma forma que os modelos (models) usando uma classe Python. De forma padrão insira o novo formulário no diretório de aplicação (forms.py). from django import forms ESCOLHA = (( 'geral', 'Informações gerais'),('erro','Relatar erro'), ('sugestao','Sugestão'),) class ContatoForm(forms.Form): topico = forms.ChoiceField(choices=ESCOLHA) mensagem=forms.Charfield(widget=forms.Textarea()) #mensagem=.....,initial=”digite sua mensagem”) põe uma mensagem no #campo usuario=forms.EmailField(required=False) No nosso formulário temos 3 campos: Tópico, Mensagem e email do usuário. O nosso objeto formulário faz um número de coisas bastante úteis como validar dados, gerar seu HTML, emitir mensagens de erro e desenhar o formulário inteiro. views.py from django.shortcuts import render_to_response from forms import ContatoForm def contato(request): form=ContatoForm() return render_to_response('contato.html',{'form':form}) Este é o template que devemos digitar: contato.html <html> <head> <title>Contato</title> </head> <body> <h1>Contato</h> <form action="." method="post"> <table> {{ form.as_table}} </table> <p><input type="submit" Value="Enviar"></p>
    • </form> </body> </html> Veja a linha que tem {{form.as_table}} no arquivo de contato.html , ela indica que iremos passar o formulário de contato como tabela, o Django vai gerar um HTML parecido com as linhas abaixo para o formulário. <tr> <th><label for="id_topico">Topico:</label></th> <td> <select name="topico" id="id_topico"> <option value="geral">Informações Gerais</option> <option value="erro">Relatar Erro</option> <option value="sugestao">Sugestão</option> </select> </td> </tr> <tr> <th><label for="id_mensagem">Mensagem:</label></th> <td><input type="text" name="mensagem" id="id_message" /></td> </tr> <tr> <th><label for="id_usuario">Usuario:</label></th> <td><input type="text" name="usuario" id="id_sender" /></td> </tr> Veja resultado digitando http://localhost:8080/contato/
    • Até agora só geramos a entrada de dados, vamos agora fazer a verificação dos dados. from django.shortcuts import render_to_response from forms import ContatoForm def contato(request): if request.method == 'POST': form=ContatoForm(request.POST) else: form=ContatoForm() return render_to_response('contato.html',{'form':form}) Veja agora se você não digitar as informações corretamente você verá as mensagens de campo obrigatório ou o aviso que você deve digitar um e-mail no campo. Uma instância do campo de formulário(forms) pode ter 2 estados, vinculado e não vinculado(bound e unbound), ou seja válido ou mostra os dados novamente. Note que depois que o formulário foi preenchido ele passa sua regra de validação e então os dados estão disponíveis e podemos fazer alguma coisa útil com eles. Se o campo usuário foi preenchido com o e-mail então podemos enviar um retorno ao usuário. 6.2 Processando o Contato – uma vez que o usuário preencheu o formulário é necessário fazer alguma coisa útil com ele. Vamos então responder ao contato através do e-mail.Vamos agora ver se o formulário está vinculado a dados válidos, então chamamos o método is_valid() e se ele for válido usaremos o método cleaned_data para pegarmos o dado mantendo seu formato Python: form=ContatoForm(request.POST) if form.is_valid(): #processa o formulário de dados topico=form.cleaned_data['topico'] mensagem=form.cleaned_data['message'] usuario=form.cleaned_data.get('usuario','semretorno@example.com'] Para o usuário foi estabelecido um e-mail caso ele não exista. Agora então enviaremos um e-mail para o administrador. from django.core.mail import send_mail ….. send_mail('Retorno, tópico: %s' % topico, mensagem, usuario, ['administrador@example.com']) E finalmente redirecionamos nosso site para a página de agradecimento.
    • return render_to_response('enviado.html') #enviado.html no diretório templates <html> <head> <title>Enviado</title> </head> <body> <h1>Enviado com sucesso!</h1> </body> </html> Para enviar o e-mail temos que usar um servidor SMTP numa porta especificada. O usuário e a senha devem ser especificados e servirão para autenticar o servidor STMP, e se a segurança for usada a variável TLS (transport layer security)deve ser True. Arquivo: settings.py …............ #coloque no final do arquivo EMAIL_HOST='smtp.gmail.com' EMAIL_HOST_USER='seu_email@gmail.com' EMAIL_HOST_PASSWORD='senha' EMAIL_PORT=587 EMAIL_USE_TLS=True Agora veja como ficou nosso arquivo views.py, no diretório contato: from django.core.mail import send_mail from django.shortcuts import render_to_response from forms import ContatoForm def contato(request): if request.method == 'POST': form=ContatoForm(request.POST) if form.is_valid(): #processa o formulário de dados topico=form.cleaned_data['topico'] mensagem=form.cleaned_data['mensagem'] usuario=form.cleaned_data.get('usuario','semretorno@example.com') send_mail('Retorno do seu site, topico: %s'%topico ,usuario+":"+mensagem,
    • usuario,['asergionogueira@ig.com.br']) return render_to_response('enviado.html') else: form=ContatoForm() return render_to_response('contato.html',{'form':form}) O arquivo forms.py, que está no diretório contato junto com o arquivo views.py. forms.py from django import forms ESCOLHA = (( 'geral', 'Informações gerais'),('erro','Relatar erro'),('sugestao','Sugestão'),) class ContatoForm(forms.Form): topico = forms.ChoiceField(choices=ESCOLHA) mensagem=forms.CharField(widget=forms.Textarea(),initial="Digite aqui sua Mensagem") usuario=forms.EmailField(required=False) A mensagem que chegou ao administrador do site. Mostra que ela foi enviada pelo gmail e no corpo da mensagem quem mandou ela e a mensagem do usuário. Referência Bibliográfica: 1. Bennett, James. Practical Django Projects. Editora Apress, 2008. 2. Brandão, Marinho. Aprendendo Django no Planeta Terra. 2009. 3. Holovaty, Adrian and Kaplan-Moss, Jacob. The Definitive Guide to Django Web Development Done Right. Editora Apress, 2008. 4. http://docs.djangoproject.com/en/1.1/