Django Módulo Básico Parte I - Desenvolvimento de uma aplicação Web

12,370 views
12,196 views

Published on

Desenvolvendo uma aplicação web com o Django

Published in: Education, Technology
0 Comments
15 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
12,370
On SlideShare
0
From Embeds
0
Number of Embeds
12
Actions
Shares
0
Downloads
810
Comments
0
Likes
15
Embeds 0
No embeds

No notes for slide

Django Módulo Básico Parte I - Desenvolvimento de uma aplicação Web

  1. 1. Django Módulo Básico Desenvolvendo uma aplicação WEB usando o framework DJANGO (parte I) Antonio Sérgio Nogueira 2010
  2. 2. Sumário 1. Django(sua história)..........................................................................................3 2. O que é o Django...............................................................................................3 3. O padrão MVC usado pelo Django..................................................................4 4. Minha primeira aplicação.................................................................................5 5. Nossa Aplicação usando modelo MTV............................................................14 6. Interagindo com banco de dados.....................................................................28 7. A administração de site do Django ….............................................................37 8. Visualizando os dados cadastrados no banco de dados.................................43 9. Disponibilizando um CMS(Sistema de gerenciamento de conteúdo)...........45 10. Referência Bibliográfica..................................................................................48
  3. 3. 1. Django(sua história) – surge em 2003 da necessidade dos programadores Adrian Holovaty e Simon Willison do jornal Lawrence Journal-World de atender uma demanda do jornalismo em tempo real, desenvolvido pelo jornal. O Django vem suprir a necessidade do jornal de ter uma ferramenta capaz de fazer a manutenção e agregar novas características em vários sites de forma bem rápida e eficiente. Nascido neste ambiente o Django é capaz de atender a necessidade de sites de conteúdo dinâmico e que possuem um grande banco de dados, e ainda tem como característica principal ser um produto open source(Licença BSD – Berkeley Software Distribution) e com uma equipe de desenvolvedores que produzem aplicações de fácil manutenção e grande performance em ambientes com grandes cargas. 2. O que é o Django - é uma estrutura(framework) para desenvolvimento web, desenvolvida na linguagem Python, que reduz tempo e permite construir aplicações WEB com qualidade e de fácil manutenção. A estrutura é coesa e fracamente acoplada, dessa forma as partes que compõe a estrutura apesar de conectadas não dependem uma das outras, com isto é possível usar e modificar parte dela sem ter que alterá-la toda. Além disso o Django usa rigidamente o princípio Don't Repeat Yourself(DRY), através do qual cada parte do código ou de dados distinta reside em um único local, tornando fácil a manutenção. Nos idos de 1998, escrevíamos aplicações Web usando o padrão CGI, que é bastante simples.
  4. 4. Veja exemplo: #!/usr/bin/python # abre um banco de dados e lista os 20 ultimos livros publicados import MySQLdb print "Content-Type: text/html" print print "<html><head><title>Livros</title></head>" print "<body>" print "<h1>Livros</h1>" print "<ul>" connection = MySQLdb.connect(user='sergio', passwd='senha', db='livro_db') cursor = connection.cursor() cursor.execute("SELECT nome FROM livros ORDER BY data_public DESC LIMIT 20") for row in cursor.fetchall(): print "<li>%s</li>" % row[0] print "</ul>" print "</body></html>" connection.close() Podemos ver que este código além de simples, pode ser enviado deste modo a um servidor(deploy ou implantação), basta salvá-lo como livros.cgi e enviá-lo ao servidor WEB e pronto ele já pode ser visitado com um browser. Mas com o crescimento da rede vários problemas apareceram: • 1. o que acontece se várias pessoas acessam a página que conecta-se ao banco de dados, possivelmente não devemos duplicar o código dos scripts e sim compartilhá-los; • 2. o desenvolvedor web deve-se preocupar com detalhes do código e lembrar que tem fechar o banco de dados; • 3. o que acontece com o reuso do código em múltiplos ambientes com vários bancos e senhas; • 4. Se é necessário redefinir a página, como fazemos isso de uma forma fácil? Estes problemas tem solução com o uso do Django um Framework Web. 3. O padrão MVC usado pelo Django – ao desenvolvermos uma aplicação com o Django notamos que existe uma divisão do software em 3 partes: models.py, views.py e urls.py. Esta divisão baseada no modelo MVC ( modelo, vista e controle) tem uma adaptação no Django e passa a ser MTV(modelo,template e vista). • Modelo- é responsável por conter a descrição das tabelas de dados em classes python, que podem criar, recuperar, atualizar e apagar registros usando simples comandos Python – arquivo models.py • Template – é a camada que define como os dados devem ser apresentados ao usuário. (Camada Vista ou View no modelo MVC). Um arquivo do tipo HTML descreve o designer da página. • View – é a camada que descreve quais os dados que serão apresentados. A lógica do negócio(Controle) é responsável pela chamada da vista correta para
  5. 5. cada requisição de URL. O arquivo que contém este controle é urls.py que esta na estrutura do Django. Estas partes quando agregadas formam o modelo MVC, que possui uma fracamente acoplagem entre elas, com isto as mudanças efetuadas em cada uma delas são independentes. Além desses recursos o Django oferece recursos avançados como configuração de URL, interface administrativa automática, armazenamento cache e uma abordagem de baterias incluídas, ou seja vem junto com o pacote uma biblioteca adicional que evita downloads adicionais. Exemplo a seguir modelo MVC. # arquivo models.py(modelo da base de dados) from django.db import models class Livro(models.Model): nome = models.CharField(maxlength=50) data_public = models.DateField() # arquivo views.py (juntamente com a urls.py é lógica do negócio) from django.shortcuts import render_to_response from models import Livro def ultimos_livros(request): lista_livros = Livro.objects.order_by('-data_public')[:20] return render_to_response('ultimos_livros.html', {'lista_livros': lista_livros}) # arquivo urls.py (configuracao URL) from django.conf.urls.defaults import * import views urlpatterns = patterns('', (r'latest/$', views.ultimos_livros), ) # arquivo ultimos_livros.html ( template – vista do négocio) <html><head><title>Livros</title></head> <body> <h1>Livros</h1> <ul> {% for livro in lista_livros %} <li>{{ livro.nome }}</li> {% endfor %} </ul> </body></html> 4. Minha primeira aplicação – antes de começarmos a aplicação usando o Django é necessário instalarmos o Python. Como ele é escrito 100% em Python você só precisa instalar o Python em seu sistema. Django necessita de Python 2.3 ou mais recente, para a versão 0.96. Verifique a versão atual e qual Python usar. Eu particularmente estou usando Python 2.5.4 com Django versão 1.0.2.0. http://www.python.org/download/ e http://www.djangoproject.com/download/
  6. 6. Para saber a versão do Django instalada entre no idle do Python e digite: >>>import django >>>django.VERSION (1, 0, 2, 'final', 0) Não esqueça o Django é uma bilbioteca do Python. Existem várias formas de instalar o Django e também temos vários sistemas operacionais onde ele roda, então basta seguir a documentação que você encontra na internet. É necessário ter noções básicas de Python. Recomendação básica a seguir: A etapa inicial da instalação do release oficial do Django é obter o tarball da página de download do Django. Após ter transferido esse arquivo por download, extraia seu conteúdo. No Linux, emita o comando em sua linha de comando do shell (certifique-se de navegar até o diretório onde transferiu por download o pacote). Observe que a V1.0.2 era o release atual da época, portanto, certifique-se de substituir esse nome de arquivo pelo nome do arquivo exato do pacote transferido por download: tar zxvf Django-1.0.2-final.tar.gz. No Mac OS X, seu navegador da Web provavelmente descompactou automaticamente o pacote quando concluiu o download, portanto, o arquivo será Django-1.0.2-final.tar. Para extrair esse arquivo, use o seguinte comando: tar xvf Django-1.0.2-final.tar. No Windows, é possível usar um utilitário como o 7-Zip para extrair o tarball. Agora que já extraiu o conteúdo do tarball (provavelmente para um local como Django-1.0.2 na unidade de disco rígido), navegue até essa pasta. . Para instalar o Django, emita o seguinte comando (Mac OS X ou Linux), no prompt de comandos: sudo python setup.py install. Para usuários do Windows, certifiquem-se de que seu prompt de comandos seja aberto com privilégios de administrador e emita o seguinte comando: python setup.py install. Após fazer isso, o Django terá sido instalado na pasta site-packages na instalação de Python e você está pronto para iniciar o desenvolvimento no Django. Para verificar se o Django está instalado corretamente. Veja tabela anterior. 4.1 Instalando um banco de dados – se você quiser usar o Django como servidor de páginas dinâmicas não é necessário ter um banco de dados. Apesar de não ser necessário usar um banco de dados, a maioria das aplicações desenvolvidas para web possui um banco de dados onde são armazenadas as informações dos sites. Existem vários banco de dados que podem ser usados com o Django os mais comuns são: PostgreSQL, SQLite e MySQL, procure no site do Django para maiores informações. Sugerimos usar em sua base local o SQLite e em ambiente de produção usar os outros. Para usar estes bancos de dados você precisa dos pacotes: psycopg, pysqlite e MySQLdb vá ao site do Django e baixe o arquivo necessário. 4.2 Mãos a obra – para começarmos a desenvolver uma aplicação em Django, o primeiro passo é começarmos um projeto, que nada mais é que a definição básica da instância do Django, incluindo base de dados, opções do software e opções específicas da aplicação. Comece então definindo o diretório para iniciar o trabalho projetodjango, agora entre neste diretório.
  7. 7. Atenção você deve ter o django-admin.py instalado através do utilitário setup.py veja a página http://www.djangoproject.com/download/ ou veja tabela anterior.( Para instalar o django abra uma pasta de nome Django crie um arquivo chamado instalar.bat e dentro dele coloque os comandos python setup.py install e pause em linhas separadas. Agora é só executar o arquivo. Este diretório é o local onde você descompactou o arquivo de download do Django. Você deve atualizar a variável path do sistema operacional para o sistema localizar o python. Utilize este endereço para instalar facilmente o Django http://www.marinhobrandao.com/blog/djangostack-facil-para-o-iniciante-aprender- django/ ou diretamente http://bitnami.org/stack/djangostack ) 4.2.1 Iniciando o projeto – primeiro criamos o diretório, entramos no diretório e executamos o comando do django (estamos no ambiente windows e o Django está instalado). Entramos no prompt de comando e digitamos: cd mkdir c:projetodjango cd c:projetodjango python c:Python25Scriptsdjango-admin.py startproject meu_site entre no diretório gerado e veja os arquivos criados (este é o projeto): cd meu_site dir meu_site/ manage.py ( Utilitário Django para gerenciar a aplicação) settings.py ( Configuração do projeto Django) urls.py ( Declarações de URL do Django) __init__.py (Arquivo do Python para tratar o diretório como um pacote) Atenção não coloque seus programas no diretório base, por medidas de segurança. 4.2.2 O servidor de desenvolvimento – o Django possui um construtor interno de servidor que pode ser usado enquanto você desenvolve seu site. Durante o desenvolvimento use este servidor, que facilita seu trabalho e dispensa a configuração do Apache. Este servidor tem um sistema de recarga que ocorre sempre que a aplicação é modificada. Abra o bloco de notas e digite o arquivo abaixo de nome: executa.bat. python manage.py runserver pause Execute o arquivo .bat e veja o servidor em execução.
  8. 8. Agora entre o browser e digite: http://localhost:8000/ e veja o Django. Pronto agora você tem um ambiente de desenvolvimento Django ativado e executando. É fácil de usar este servidor, mas ele não é seguro e foi feito apenas para executar apenas uma requisição por vez. Para executar o servidor para outra porta digite: python manage.py runserver 8080 ou python manage.py runserver 0.0.0.0:8080 para definir IP, neste caso o Django ouve qualquer interface de rede permitindo outros computadores se conectar ao servidor de desenvolvimento. 4.2.3 Uma página dinâmica – uma página dinâmica nada mais é que a execução de um script quando a página é executada. Esse script é que vai gerar a página. Neste momento não iremos usar nenhum banco de dados. Para criar esta página iremos então gerar uma função view que vai aceitar um pedido da web retornar uma resposta, esta resposta pode ser uma imagem, um erro 404, um documento XML ou uma página HTML. Vamos criar então um arquivo chamado views.py e armazená-lo no diretório do site. Vamos ao código: from django.http import HttpResponse from time import time,localtime def dataatual(request): a, ms, d, h, m, s=localtime(time())[0:6] html='''<html><body> <h1>Data: %02d/%02d/%02d Hora : %02d:%02d:%02d'''%(d,ms,a,h,m,s) html=html+'</body></html>' return HttpResponse(html)
  9. 9. Sempre que editar com bloco de notas e definir a opção UTF-8, para que todos os caracteres apareçam corretamente. Vamos agora definir o fuso-horário do nosso sistema, já que trabalhamos com data e hora. Entre no arquivo settings.py e modifique o TIME_ZONE para 'America/Sao_Paulo'. Verifique na janela do servidor(janela com o prompt de comando) que ele é executado novamente assim que você modifica o arquivo. 4.2.4 Vamos ver a página dinâmica sendo executada – para que esta função view seja executada devemos mapeá-la para uma URL, de forma que o Django encontre esta função. O arquivo de URL nada mais é que um arquivo de configuração que determina qual página deve ser apresentada quando é feita uma requisição. Atenção ao procurar uma função para execução o python procura de acordo com seu path. No shell do IDLE do Python digite os comandos abaixo e veja o path. >>>import sys >>>sys.path Configuração do meu micro: Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. **************************************************************** Personal firewall software may warn about the connection IDLE makes to its subprocess using this computer's internal loopback interface. This connection is not visible on any external interface and no data is sent to or received from the Internet. **************************************************************** IDLE 1.2.4 >>> import sys >>> sys.path ['C:Python25Libidlelib', 'C:Python25libsite-packagesroutes-1.11- py2.5.egg', 'C:WINDOWSsystem32python25.zip', 'C:Python25DLLs', 'C:Python25lib', 'C:Python25libplat-win', 'C:Python25liblib-tk', 'C:Python25', 'C:Python25libsite-packages', 'C:Python25libsite-packages gtk-2.0', 'C:Python25libsite-packageswin32', 'C:Python25libsite- packageswin32lib', 'C:Python25libsite-packagesPythonwin', 'C:Python25libsite-packageswx-2.8-msw-unicode'] >>> O arquivo urls.py vai ficar assim: from django.conf.urls.defaults import * from meu_site.views import dataatual
  10. 10. # 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'^data/$',dataatual), # ^ e $ são usados para assegurar que só a rota /data será # encontrada ) Atenção expressão regulares como [A-Z] qualquer caracter de A a Z também é possível. Exemplo: (r'^data[a-z]/$',dataatual) ou também (r'^data/*',dataatual) todas as rotas de data usam a URL. . (dot) Any character d Any digit [A-Z] Any character from A-Z (uppercase) [a-z] Any character from a-z (lowercase) [A-Za-z] Any character from a-z (case-insensitive) [^/]+ All characters until a forward slash (excluding the slash itself) + One or more of the previous character (e.g., d+ matches one or more digit) ? Zero or more of the previous character (e.g., d* matches zero or more digits) {1,3} Between one and three (inclusive) of the previous character 4.2.5 Como o Django processa as requisições – ao executarmos o software o programa importa as configurações de um arquivo chamado settings.py, que contém também a configuração mais importante chamada de ROOT_URLCONF que é a entrada do nosso site, esta configuração é automaticamente gerada ao iniciarmos nosso projeto. Ao chegar a requisição /data/ o Django carrega o root e depois checa na sequência qual das URLs atende a chamada, então chama a função view associada e passa ao objeto HttpResponse o primeiro parâmetro para a função. A função então é responsável por retornar o objeto HttpResponse. Internamente o sistema de requisição funciona assim: Uma requisição HTTP vem do browser, um manipulador específico gera uma HttpRequest que chama um middleware de Requisição e se houver uma vista chama o middleware view disponível, caso haja uma exceção de Request ela é
  11. 11. enviada diretamente ao middleware response e de View ela é enviada ao middleware de Exceção e será retornada através de uma vista default que gera uma resposta 404 ou 500 amigável, que é enviada ao middleware de resposta, que gera um HttpResponse. Finalmente o sistema processa a requisição através de uma vista (view) e a resposta é enviada para o Middleware de reposta que gera um HttpResponse. 4.2.6 Baixo acoplamento – neste tipo de programação o importante é gerar módulos ou pedaços de software intercambiáveis, com isto dizemos que dois pedaços de códigos são de baixo acoplamento, quando a mudança efetuada em um deles não tem efeito sobre o outro e se tem o efeito é bem reduzido. O Django possui este tipo de acoplamento entre as URLs e as funções que atendem as VIEWS. Um exemplo disto pode ser visto no desenvolvimento que fizemos pois podemos mudar o nome da URL sem mexer na vista(VIEWS).
  12. 12. 4.2.7 Retornando erro – quando uma URL diferente da que definimos for acessada o Django retorna uma mensagem de erro. Esta página só é mostrada quando o Django está no modo de DEBUG. 4.2.8 Passando um parâmetro pela URL – é possível passar uma informação através da URL, no caso do Django, isto pode ser feito da seguinte forma: #arquivo views.py from django.http import HttpResponse from time import time,localtime import datetime def dataatual(request): a, ms, d, h, m, s=localtime(time())[0:6] html='''<html><body> <h1>Data: %02d/%02d/%02d Hora é: %02d:%02d:%02d'''% (d,ms,a,h,m,s) html=html+'</body></html>' return HttpResponse(html) def maisdataatual(request, offset): # adiciona uma hora na data offset=int(offset) a, ms, d, h, m, s=(localtime(time()+offset*3600))[0:6] html='''<html><body> <h1>Data: %02d/%02d/%02d Hora é: %02d:%02d:%02d'''% (d,ms,a,h,m,s) html=html+'</body></html>' return HttpResponse(html)
  13. 13. # arquivo urls.py from django.conf.urls.defaults import * from meu_site.views import dataatual,maisdataatual # 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'^data/$',dataatual), (r'^data/(d{1,2})/$',maisdataatual), #d{1,2} captura somente 2 dígitos. ) Digite esta URL e você verá: http://localhost:8080/data/1/ 4.2.9 Ocasionando um erro de programação - Modifique o arquivo views.py de tal forma que a linha offset fique desta forma: #offset=int(offset) Ao fazermos isto introduzimos um erro no programa e o Django mostrará ele na tela da seguinte forma:
  14. 14. No topo da página temos a informação chave do erro que é o arquivo e a linha que tem o erro. Na linha Traceback você terá um link, com detalhamento, para conseguir apoio nas listas de suporte(clique no link) e nas linhas em negrito você terá um detalhamento do programa(clique nelas). No termo Local vars temos as variáveis locais(clique ali). 5. Nossa Aplicação usando modelo MTV – vimos anteriormente que o código HTML está embutido dentro do código Python, este arranjo pode apresentar alguns problemas como a mudança de código, sempre que o projeto de layout da página mude, e o profissional de web designer tem que programar Python. Por esta razão é
  15. 15. muito mais claro e manutenível ter o código separado do designer da página. Desta forma usaremos o sistema de template do Django. 5.1 Sistema Básico de Templates – No Django a template é uma string que separa a apresentação de um documento de seus dados. Uma template define a forma e os vários pedaços da lógica básica que definem como o modelo deve ser mostrado. Geralmente templates são usados para produzir HTML, mas em Django eles são também capazes da geração de qualquer formato de texto. Exemplo: <html> <head><title>Aviso</title></head> <body> <p>Caro {{nome_cliente}},</p> <p>Obrigado por contatar a empresa {{companhia}}. Esta agendado para {{ agenda_data|data:”F j, Y”}}.</p> <p>Aqui estão seus avisos:</p> <ul> {% for item in item_list %} <li>{{item}}</li> {%endfor%} </ul> {%if ordem%} <p>Sua informação foi incluida.</P> {%endif%} <p>Obrigado,<br />>{{companhia}}</p> <body> </html> Neste exemplo temos um arquivo HTML com template de variáveis e tags padrões, vejamos: • Qualquer texto cercado por parênteses duplos é uma variável; • Qualquer texto cercado por {% ( uma tag padrão) significa que o sistema deve executar o comando que está entre elas( {% for....%} , {%if....%}; • O tag {% variavel | filtro %} é um filtro que altera a forma que mostra o conteúdo da variável, é possível criar seu próprio filtro e tag; • As variáveis tem nomes iniciados com uma letra (A-Z ou a-z)e podem conter dígitos, sinal gráfico sublinhado e ponto e as maiúsculas são diferentes das minúsculas; Vá no diretório do projeto e digite : python manage.py shell
  16. 16. >>> from django.template import Context, Template >>> t = Template("Meu nome eh {{ name }}.") >>> c = Context({"name": "Sergio"}) >>> print t.render(c) 'Meu nome eh Sergio.' Primeiro nós criamos a template t, depois o objeto contexto que mapeia as variáveis e depois chamamos o método render() do nosso objeto template passando a ele o contexto, com isto as variáveis serão substituídas pelos valores atuais e serão executados o blocos tags como {%if %} por exemplo que estiver dentro da template(veja exemplo quadro anterior).Caso haja um erro dentro da estrutura do Template ele retornará o erro TemplateSyntaxError. >>> from django.template import Template >>> t = Template('{% nadatag %} ') Traceback (most recent call last): File "<stdin>", line 1, in ? ... django.template.TemplateSyntaxError: Invalid block tag: 'nadatag' 5.2 Passando variáveis de contexto complexas – a chave para passarmos variáveis complexas é caracter “.”(dot ), ele é usado para acessar chaves de dicionários, atributos, índices e métodos de um objeto. >>> pessoa = {'nome':'sergio', 'idade':'23'} >>>t=Template('{{pessoa.nome}} tem {{pessoa.idade}} anos.') >>>c=Context({'pessoa':pessoa}) >>>t.render(c) >>>x=Template('{{pessoa.nome.upper}}') >>>x.render(c) >>>t=Template('Item 2 eh {{item.2}}.') >>>c=Context({'item':['abacaxi','banana','abacate']}) >>>print t.render(c) Item 2 eh abacate. Atenção em caso de erro ou exceção gerada em um método, ela se propagará até encontrar uma exceção com um atributo silent_variable_failure igual a True, senão o sistema executa o método como uma string vazia. Alguns métodos podem ter efeito colateral e furar a segurança permitindo que o sistema os acesse. Por exemplo se você possui um objeto ContaBancaria que possui um método chamado apagar(), o modelo deve proibí-lo de inclui alguma coisa como {{conta.apagar}}, para isto existe um atributo chamado alters_data no método. Exemplo: def apaga(self): #apaga uma conta apaga.alters_data=True Quando incluirmos {{conta.apagar}} o sistema falha silenciosamente. 5.3 Como são manipulados variáveis inválidas – as variáveis que não existem são processados como sendo strings vazias, e não ocasionam exceções, isto pode se alterado.
  17. 17. 5.4 Trabalhando com objetos de contexto – sempre passamos todos os parâmetros usados, mas podemos alterá-los adicionando e apagando itens de um contexto. >>>c=Context({“horas”:”10”}) >>>c[“horas”] '10' >>>del c[“horas”] >>>c[“horas”] '' >>>c[“data”]='25/10' >>>c[“data”] '25/10' 5.5 Tags e Filtros Básicos do Modelo – vamos ver as principais tags e filtros do modelo Django (Template). Tags: - if/else {% if <condição> %} ---> lista vazia, tupla vazia, dicionário vazio, string vazia, zero e None são falsos no contexto booleano. …..... {% else %} ----> opcional {% endif %} valores and, or e not são aceitos na expressão de decisão. - for {% for variavel in lista_de_variavel %} → pode-se aninhar o comando. ….... {% endfor} Como não temos suporte para sair do loop antes do final, temos algumas variáveis mágicas do modelo: forloop.counter – contador de loops, forloop.revcounter – contador reverso, forloop.first – variável setada na primeira interação, forloop.last – variável setada na última interação e forloop.parentloop é uma referência para o objeto pai no caso de loops aninhados. Estas variáveis não existem fora do loop. {% for item in todo_list %} <p>{{ forloop.counter }}: {{ item }}</p> {% endfor %} {% for object in objects %} {% if forloop.first %}<li class="first">{% else %}<li>{% endif %} {{ object }} </li>
  18. 18. {% endfor %} {% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %} {% for country in countries %} <table> {% for city in country.city_list %} <tr> <td>Country #{{ forloop.parentloop.counter }}</td> <td>City #{{ forloop.counter }}</td> <td>{{ city }}</td> </tr> {% endfor %} </table> {% endfor %} - ifequal/ifnotequal {% ifequal <argumento> <argumento1> %} ou {% ifnotequal <argumento> <argumento1> %} …... {% else %} → opcional …... {% endifequal %} {% ifequal usuario usuariocorrente %} <h1>Bem-vindo!</h1> {% endifequal %} {% ifequal variable 1 %} {% ifequal variable 1.23 %} {% ifequal variable 'foo' %} {% ifequal variable "foo" %} {% ifequal variable {'key': 'value'} %} -Comentário {# Isto eh comentario #} Filtros: forma simples de alterar conteúdos. {{name|lower}} – converte nome para minúsculo. {{meutexto|escape|linebreaks}} – filtra texto colocando no lugar de escape a quebra de linha <p>. {{texto|truncatewords:”30”}} - mostra as 30 primeiras palavras do texto, usar aspas. {{data| data: “F j, Y”}} - formata a data.
  19. 19. lenght , escape, addslashes – são outros filtros. 5.6 Vamos agora usar os templates(modelos) e variáveis de contexto nos arquivos de views(vistas) – antes de separar as views do código HTML. Vamos ver o exemplo abaixo usando a classe template no arquivo de views: #views.py # deixando o html no proprio arquivo from django.template import Template, Context from django.http import HttpResponse from time import time,localtime def dataatual(request): a, ms, d, h, m, s=localtime(time())[0:6] # maneira simples de acessar o template t=Template('''<html><body>Data: {{ano}}/{{mes}}/{{dia}} Hora : {{hora}}:{{min}}:{{seg}} </body></html>''' html=t.render(Context({'ano':a,'mes':ms,'dia':d,'hora':h,'min':m,'seg':s})) return HttpResponse(html) def maisdataatual(request, offset): offset=int(offset) a, ms, d, h, m, s=(localtime(time()+offset*3600))[0:6] t=Template('''<html><body><h1>Data: {{ano}}/{{mes}}/{{dia}} Hora : {{hora}}:{{min}}:{{seg}}</h1> </body></html>''') html=t.render(Context({'ano':a,'mes':ms,'dia':d,'hora':h,'min':m,'seg':s})) return HttpResponse(html) Digite esta URL : http://localhost:8000/data/1/ ou http://localhost:8000/data/ 5.7 Aplicação usando o arquivo de template: Vamos salvar o Template em um arquivo e usar o Python para ler o arquivo. #views.py from django.template import Template, Context from django.http import HttpResponse from time import time,localtime def dataatual(request): a, ms, d, h, m, s=localtime(time())[0:6] # acessando um Template que esta num arquivo fp=open('/projetodjango/meu_site/templates/meutemplate.html') t=Template(fp.read()) fp.close() html=t.render(Context({'ano':a,'mes':ms,'dia':d,'hora':h,'min':m,'seg':s}))
  20. 20. return HttpResponse(html) def maisdataatual(request, offset): offset=int(offset) a, ms, d, h, m, s=(localtime(time()+offset*3600))[0:6] t=Template('''<html><body><h1>Data: {{ano}}/{{mes}}/{{dia}} Hora : {{hora}}:{{min}}:{{seg}}</h1> </body></html>''') html=t.render(Context({'ano':a,'mes':ms,'dia':d,'hora':h,'min':m,'seg':s})) return HttpResponse(html) #arquivo meutemplate.html no diretório anteriormente estipulado <html> <body> <h1>Data: {{ano}}/{{mes}}/{{dia}} Hora : {{hora}}:{{min}}:{{seg}}</h1> </body> </html> Esta solução não é das melhores pois se o arquivo der erro acontecerá uma exceção de I/O, fora que você acaba tendo muito código se você definir um Template para cada função. Para resolver este problema vamos estudar um modelo de carga e diretório usado pelo Django. 5.8 Modelo de Carga – o Django fornece uma conveniente e potente API para carga de Templates do disco, com isto ele elimina redundâncias de carregamento das templates. Em primeiro lugar devemos informar onde armazenamos nossas templates no arquivo de settings. No nosso diretório de projeto o Django já criou o arquivo de nome settings.py, que contém informações como estas não necessariamente nesta ordem. Estas informações são simples variáveis Python: DEBUG = True TEMPLATE_DEBUG = DEBUG TIME_ZONE = 'America/Sao_Paulo' USE_I18N = True ROOT_URLCONF = 'meu_site.urls' Continuamos a verificar o arquivo e encontramos uma tupla TEMPLATES_DIRS, é neste local que devemos definir nosso diretório. Veja ela está vazia. TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or # "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. 'c:/projetodjango/meu_site/templates', ) Recomenda-se criar um diretório templates dentro do projeto Django. Não esqueça
  21. 21. de colocar uma vírgula no final da string de template quando a tupla tiver um elemento. No windows recomenda-se usar a letra do drive e usar barra '/' e não '' barra ao contrário. No exemplo abaixo usamos uma função do Python para determinar o caminho dinamicamente. import os.path TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or # "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. os.path.join(os.path.dirname(__file__),'templates').replace('','/'), ) Uma vez que definimos o endereço da template podemos agora utilizá-lo na nossa view e deixá-la como acima. # deixando o html no proprio arquivo from django.template.loader import get_template from django.template import Template, Context from django.http import HttpResponse from time import time,localtime def dataatual(request): a, ms, d, h, m, s=localtime(time())[0:6] t= get_template('meutemplate.html') html=t.render(Context({'ano':a,'mes':ms,'dia':d,'hora':h,'min':m,'seg':s})) return HttpResponse(html) def maisdataatual(request, offset): offset=int(offset) a, ms, d, h, m, s=(localtime(time()+offset*3600))[0:6] t= get_template('meutemplate.html') html=t.render(Context({'ano':a,'mes':ms,'dia':d,'hora':h,'min':m,'seg':s})) return HttpResponse(html) Aqui nós usamos a função django.template.loader.get_template() em vez de carregar o arquivo manualmente. Se o arquivo não existir o Django mostra a seguinte tela, onde ele diz qual arquivo tentou carregar e porque ele não conseguiu, se existir mais diretórios dentro da variável TEMPLATE_DIRS cada um deles será checado.
  22. 22. render_to_response() - como no Django é comum carregar o template, preencher o contexto e retornar um objeto de resposta http, ele fornece um caminho mais curto para fazer isto é uma função chamada render_to_response(), que está no módulo django.shortcuts. # deixando o html no proprio arquivo from django.shortcuts import render_to_response from time import time,localtime def dataatual(request): a, ms, d, h, m, s=localtime(time())[0:6] return render_to_response ('meutemplate.html',{'ano':a, 'mes':ms,'dia':d,'hora':h,'min':m,'seg':s}) def maisdataatual(request, offset): offset=int(offset) a, ms, d, h, m, s=(localtime(time()+offset*3600))[0:6] return render_to_response ('meutemplate.html',{'ano':a,
  23. 23. 'mes':ms,'dia':d,'hora':h,'min':m,'seg':s}) Veja que o primeiro argumento de render_to_response é o template usado e o segundo, quando dado, deve ser o dicionário usado na criação do contexto. Função locals() - você pode notar definimos as variáveis e depois temos que passá- las através de função, em vez de passá-las uma a uma podemos utilizar a função locals para fazer isto. Esta função retorna o dicionário das variáveis locais juntamente com seus valores. Veja exemplo: # deixando o html no proprio arquivo from django.shortcuts import render_to_response from time import time,localtime def dataatual(request): ano, mes, dia, hora, min, seg=localtime(time())[0:6] return render_to_response ('meutemplate.html',locals()) def maisdataatual(request, offset): offset=int(offset) ano, mes, dia, hora, min, seg=(localtime(time()+offset*3600))[0:6] return render_to_response ('meutemplate.html',locals()) #veja que atribuímos as variáveis o mesmo nome que elas possuem no HTML Esta função ocasiona um pequeno overhead no sistema, porque ela tem que gerar este dicionário dinamicamente. Função get_template – usada para buscar templates que ficam armazenadas num sub-diretório do diretório atual, que é o padrão do Django, vista anteriormente. t=get_template('templates/meutemplate.html') #atenção utilize o padrão de diretório do Unix '/' Tag include - esta tag permite a inclusão de conteúdos de outro template. Exemplos: Incluindo um template exemplo.html {% include 'exemplo.html' %} {% include “exemplo.html” %} Incluindo o template de um sub-diretório includes {% include 'includes/exemplo.html' %} Incluindo o template cujo nome está dentro de uma variável {% include nome_template %} Não se esqueça que para gerar a rota onde está o arquivo o sistema sempre utiliza o diretório definido em TEMPLATE_DIRS, válido também para a função
  24. 24. get_template(). Herança no Template – a forma clássica de reduzir código HTML é usar os includes no lado do servidor, como citado anteriormente. De fato, o Django suporta essa abordagem {%include ….. %}, mas a melhor forma de resolver este problema é usando a template herança. O que na realidade fazemos é gerar um esqueleto da template com todas as partes comuns do site e definir blocos filhos que são templates que podem ser sobrepostos. Veja um exemplo mais completo: # neste exemplo mostramos a hora <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="pt-br" <head> <title>Hora</title> </head> <body> <h1>A informação: </h1> <p> {{hora}}:{{min}}:{{seg}} </p> <hr> <p> Obrigado pela Visita. </p> </body> </html> # neste outro a data <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="pt-br" <head> <title>Data</title> </head> <body> <h1>A informação: </h1> <p> {{ano}}/{{mes}}/{{dia}} </p> <hr> <p> Obrigado pela Visita. </p> </body> </html> Claramente nestes dois exemplos temos alguns trecho de códigos que se repetem, imagine um site com barra de navegação, planilha de estilos, código Java e temos que
  25. 25. colocar esta informação em cada uma das templates. No lado do servidor a solução deste problema é fatorar as partes de ambas templates e gerar arquivos templates com pequenos trechos de códigos comuns. Por exemplo poderíamos gerar o template de cabeçalho num arquivo chamado cabecalho.html . # cabecalho.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="pt-br" <head> Rodapé : #rodape.html <hr> <p> Obrigado pela Visita. </p> </body> </html> Agora podemos notar que esta estratégica funciona bem para rodapé e cabeçalho. E no meio do arquivo como é que fica? Ai que entra a solução de herança para resolver facilmente este problema. Em vez de definir trechos de códigos comuns, definimos trechos de códigos diferentes. Em primeiro lugar definimos a template base, um esqueleto da template filho que depois será preenchido. #base.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="pt-br" <head> <title>{%block titulo %} {%endblock %}</title> </head> <body> <h1>{%block titulo1 %} {%endblock %}</h1> <p> {%block conteudo %} {%endblock %}</p> <hr> <p> Obrigado pela Visita. </p> </body> </html> Este documento define o esqueleto do documento HTML, que será usado pelas outras páginas do site. Neste template as tags block definem os locais onde serão feitas as substiuições. Agora basta modificar a template meutemplate.html. 5.9 Uma nova aplicação usando as técnicas e funções de template do Django - Vamos ver nosso sistema agora modificado para mostrar data e hora usando as novas templates.
  26. 26. # arquivo urls.py from django.conf.urls.defaults import * from meu_site.views import dataatual,horaatual # 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'^hora/$',horaatual), (r'^data/$',dataatual), ) #arquivo views.py # deixando o html no proprio arquivo from django.shortcuts import render_to_response from time import time,localtime def dataatual(request): ano, mes, dia, hora, min, seg=localtime(time())[0:6] return render_to_response ('meutemplatedata.html',locals()) def horaatual(request): ano, mes, dia, hora, min, seg=localtime(time())[0:6] return render_to_response ('meutemplatehora.html',locals()) #arquivo base.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="pt-br"
  27. 27. <head> <title>{% block titulo %} {% endblock %}</title> </head> <body> <h1>{% block titulo1 %}{% endblock %}</h1> <p> {% block conteudo%}{% endblock %}</p> <hr> <p> Obrigado pela Visita. </p> </body> </html> # arquivo meutemplatedata.html {%extends "base.html" %} {%block titulo %}Tempo{%endblock %} {%block titulo1%}Data:{%endblock%} {%block conteudo%}<p> {{dia}}/{{mes}}/{{ano}} </p>{%endblock%} #arquivo meutemplatehora.html {%extends "base.html" %} {%block titulo %}Tempo{%endblock %} {%block titulo1%}Hora:{%endblock%} {%block conteudo%}<p> {{hora}}:{{min}}:{{seg}} </p>{%endblock%} Veja agora temos um sistema que mostra a data e hora no cliente, usando templates sem repetição de código. A herança não afeta a forma de trabalho, e podemos ter vários níveis de herança. A template base.html tem o formato principal do site e normalmente não é modificada, normalmente ela é estendida para cada seção da base(cabeçalho, rodapé...). Criamos então para cada tipo de página um template(por ex: página de fotos, fóruns,....), no nosso caso data e hora, que pode ser estendido em em templates de seções também. Esta abordagem maximiza o código utilizado e torna simples adicionar componentes nas áreas partilhadas(como a seção de navegação).
  28. 28. Dicas para trabalhar com herança: – {%extends %} deve ser sempre a 1a. Tag. – Defina na template filho somente as tags {%block%} que for usar. – Códigos duplicados nas templates filho, normalmente devem ser definidos na template pai. – Não é permitida repetição de tags {%block%} de mesmo nome, porque ao duplicá-las o sistema não saberá qual usar para preencher os dados. – O nome definido em extends é o nome do template acrescido da extensão de diretório definida em TEMPLATE_DIRS. – O nome do definido em extends pode ser uma variável. 6. Interagindo com banco de dados – normalmente sites armazenam informações em banco de dados relacionais. Esta característica permite uma clara separação entre dados e lógica, da mesma forma que separamos lógica do sistema da visualização dos dados, usando views e templates. O Django é um produto direcionado para construir sites com acesso a base de dados, de forma fácil e potente usando o Python. 6.1 Acessando banco de dados em vistas (views) – existe uma forma de recuperar dados de dentro de uma vista (view). É simples, basta usar a biblioteca do Python para executar uma busca SQL e usar os resultados. Em seguida temos um exemplo usando a bilbioteca MySQLdb para conectar-se a base de dados (http://www.djangoproject.com/r/python-mysql/), recuperar alguns registros e alimentar uma template para mostrar como uma página Web. from django.shortcuts import render_to_response import MySQLdb def lista_livros(request): db=MySQLdb.connect(user='eu', db='livros', passwd='secreta', host='localhost') cursor=db.cursor() cursor.execute('SELECT nome FROM livros ORDER BY nome') nomes=[linha[0] linha row in cursor.fetchall()] db.close() return render_to_response('lista_livro.html',{'nomes':names}) Esta abordagem vai funcionar mas alguns problemas aparecem: – Idealmente a configuração dos parâmetros deve ser armazenadas na configuração do Django. – Você deve escrever detalhes como: conexão, criar cursor executar busca e fechar conexão, idealmente só deveríamos especificar o que queremos. – O código neste caso é específico para o MySQL, que se alterado vai modificar o adaptador de banco de dados, os parâmetros de conexão e possivelmente até o código. Idealmente o banco que você usa deveria ser abstraído, de tal forma que mudamos apenas a informação de qual banco usar o software se incumbe de acessar os dados. Como era de se esperar a camada de banco de dados do Django visa resolver este
  29. 29. problema e pode ser escrita desta forma: from django.shortcuts import render_to_response from meu_site.books.models import livros def lista_livros(request): livros=livro.objects.order_by('nome') return render_to_response(lista_livro.html', {'livros',livros}) 6.2 Voltando a falar do padrão de desenvolvimento MTV – ao falarmos em MVC estamos apenas agilizando a forma de comunicação entre desenvolvedores, dizendo que é para separarmos o software em camadas de acesso ao banco de dados (Model), de camada que cuida da forma como os dados são mostrados(Views) e finalmente na camada(Control) que cuida da lógica, dependendo da entrada do usuário( URL ) define a view e a função Python que trata da chamada. Como no Django a camada “C” é tratada pelo framework, temos uma classificação chamada de MTV (Model/Template/View), camada de acesso aos dados, camada de apresentação dos dados e camada de lógica do negócio, que contém uma lógica que pega os dados e define a template correta. A diferença entre elas é que em Django views são controles e templates são views, ou seja Django trata as views como sendo a forma como tratamos os dados e não como apresentamos eles (templates), já o modelo MVC os controles é que tratam dos dados e as views apresentam os dados(Ruby on Rails). 6.3 Configurando o Banco de Dados – para começarmos a trabalhar com banco dados em primeiro lugar precisamos configurá-lo, ativá-lo e criar o banco de dados, e depois informar ao Django com qual banco trabalharemos. Vamos assumir que você já criou o banco dentro do MySQL ou do PostgreSQL (através do comando CREATE DATABASE), e se for usar o SQLite não há necessidade de ter criado o banco, porque cada banco é um arquivo que ele cria para armazenar os dados. Vamos então ao arquivo settings.py e vamos configurar o banco de dados: Localize no arquivo meu_site/settings.py as linhas: DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. DATABASE_NAME = '' # Or path to database file if using sqlite3. DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. Veja na 1a. linha que você deve instalar o adaptador de banco de dados apropriado para cada um deles. Na 2a.linha o nome do banco de dados ou o caminho completo para o SQLite. Na 3a. linha o nome do usuário ou em branco para o SQLite. Na 4a. linha a senha do usuário ou em branco para o SQLite. Na 5a. linha qual host está o banco ou localhost para computador local, em branco SQLite. Na 6a. linha qual porta está o banco ou em branco para o SQLite. Deixe em branco para assumir o
  30. 30. padrão do banco. Testando o banco de dados: Execute o MySQL Comand Line Client. Forneça a senha de root para acessar o MySQL Monitor. mysql> create database livros; # comando digitado dentro MySQL monitor Query OK, 1 row affected (0.00 sec) # retorno do comando Altere o arquivo settings.py: DATABASE_ENGINE = 'mysql' DATABASE_NAME = 'livros' . DATABASE_USER = 'usuario' DATABASE_PASSWORD = 'senha' DATABASE_HOST = 'localhost' DATABASE_PORT = '' Vamos testar a configuração: Entre no diretório /projetodjango/meu_site digite: python manage.py shell >>> from django.db import connection >>>cursor=connection.cursor() >>>cursor() <django.db.backends.util.CursorDebugWrapper object at …..) Senão retornar o endereço do objeto, retorna o erro. Estamos pronto para usar o banco de dados. 6.4 Primeira Aplicação usando banco de dados – vamos agora criar uma aplicação Django que é um conjunto de código que inclui modelos, vistas, templates junto com o pacote Python. Até o presente momento só criamos um projeto DJANGO, que nada mais é que uma instância de um conjunto de aplicações Django com suas configurações. Agora vamos criar nossa aplicação que é um conjunto portável de funcionalidades Django, juntamente com suas configurações e seus códigos. Para exemplificar o Django vem com um número de aplicações como: sistemas de comentário e um sistema de administração automático, que poderão ser usadas em múltiplos projetos, e que se você for fazer uma simples aplicação talvez precise apenas de uma delas, e por outro lado se você precisa criar uma aplicação complexa
  31. 31. você pode anexar sistemas como um e-commerce e uma placa de mensagens, que você podem ser usadas individualmente no futuro. Enfim, não é necessário criar aplicações para tudo, podemos como já fizemos chamar apenas algumas views.py, e preenchê-las com funções e apontar suas URLs para essas funções, mas existe uma regra de ouro que é: sempre que usar uma camada de banco de dados você deve criar uma aplicação e seus modelos devem estar dentro. Agora chegou a hora de criarmos a aplicação e seus modelos. Dentro de seu diretório de projeto meu_site digite o comando para criar uma aplicação: python manage.py startapp livros Este comando vai criar o diretório abaixo: livros/ __init__.py models.py views.py Estes arquivos conterão seus modelos e vistas dessa aplicação. Veja que eles estão vazios, a exceção de models.py que já possui o comando para importar o banco de dados. Comentando: apesar de termos um overhead ao usar modelos isto é vantajoso por: – Concentrar num local todo o acesso ao banco de dados. – Deixar o programador focado apenas no Python. – É mais fácil manter modelos do que estrutura de dados. – Existem diferenças entre os comandos aceitos em SQL pelos bancos. – Não existem campos específicos para email. 6.4.1 Layout do nosso Model – continuamos a desenvolver nosso modelo baseado na aplicação proposta anteriormente ou seja o cadastro de livros. Vejamos os conceitos, campos e relacionamentos: ▪ O autor tem: nome, email e foto. ▪ O editor tem: nome, endereço, cidade, estado e site. ▪ O livro tem: título, autores e data de publicação. Vamos definir este layout no arquivo models.py: from django.db import models # Create your models here. class Editor(models.Model): nome = models.CharField(max_length=30) endereco = models.CharField(max_length=50) cidade = models.CharField(max_length=30)
  32. 32. estado = models.CharField(max_length=2) site = models.URLField() class Autor(models.Model): nome = models.CharField(max_length=40) email = models.EmailField() foto = models.ImageField(upload_to='/tmp') class Livro(models.Model): titulo = models.CharField(max_length=100) autores = models.ManyToManyField(Autor) editor = models.ForeignKey(Editor) data_publicacao = models.DateField() Cada modelo foi representado por uma classe Python uma subclasse de django.db.models.Model . A classe Pai contém todo software necessário para fazer estes objetos capazes de interagir com o banco de dados, deixando apenas o seu modelo ser responsável pela definição do campo. Cada modelo representa uma simples tabela de dados, e cada atributo normalmente representa uma coluna da tabela de dados. A exceção ocorre quando temos relacionamentos muitos para muitos ou seja cada livro pode ter um ou vários autores(ManyToManyField). Automaticamente o Django neste caso vai gerar uma tabela adicional de muitos- para-muitos. Outro detalhe é que o Django cria automaticamente um campo de identificação id (chave primária), a não ser que haja uma instrução contraria. O Django cria automaticamente esta tabela. 6.4.2 Instalando o Modelo e gerando as tabelas de dados – depois de escrever o código vamos criar nossas tabelas no banco de dados. Primeiro ativamos este modelo, para fazer isto vamos adicionar a aplicação livros na lista de settings.py( Estes arquivos e comandos devem ser digitados no diretório ../meu_site. Veja estas linhas e modifique-as: INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', ) MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', )
  33. 33. Transforme estas linhas em comentários e adicione a linha abaixo. INSTALLED_APPS = ( # 'django.contrib.auth', # 'django.contrib.contenttypes', # 'django.contrib.sessions', # 'django.contrib.sites', 'meu_site.livros', ) MIDDLEWARE_CLASSES = ( # 'django.middleware.common.CommonMiddleware', #'django.contrib.sessions.middleware.SessionMiddleware', #'django.contrib.auth.middleware.AuthenticationMiddleware', ) Comentamos as linhas temporariamente para retirar estas aplicações padrões. Não se esqueça de colocar vírgula após o texto, lembrando que esta variável é uma tupla. A linha 'meu_site.livros' refere-se a aplicação livros, cada aplicação é representada por uma linha separada por pontos para representar o caminho Python completo . Agora digite o comando na tela de prompt, no diretório onde encontra-se o arquivo manage.py, para validar o modelo, e a mensagem 0 errors deve ser emitida. python manage.py validate Atenção para manipular imagens o Python precisa da biblioteca PIL(Python Imaging Libray) baixe ela em: http://www.pythonware.com/products/pil/index.htm Agora criamos a tabelas do banco de dados com o comando: python manage.py sqlall livros As tabelas são geradas automaticamente combinando o nome do banco e a tabela por exemplo: livros_autor. A tabela também vai possuir o campo id que é a chave primária, as chaves estrangeiras são feitas através do comando REFERENCES. Os comandos gerados são específicos para cada banco por exemplo: campo tipo auto_increment (MySQL), serial(PostgreSQL) e integer primary(SQLite). Este comando realmente não cria as tabelas, isto é para você visualizar estas tabelas. Execute o comando a seguir e as tabelas serão geradas. python manage.py syncdb #só altera modelos, não atualiza dados, pode ser # executado sem danificar os dados resultado: Creating table livros_editor Creating table livros_autor Creating table livros_livro
  34. 34. Installing index for livros.Livros model Aviso: O que acontece durante syncdb Quando executa manage.py syncdb, primeiro o Django vê cada aplicação listada em INSTALLED_APPS e encontra os modelos de dados. Eles são classes Python que definem diferentes tipos de dados da aplicação do usuário, e o Django sabe como automaticamente gerar os comandos apropriados para criar as tabelas SQL. Depois de criado o banco de dados, o Django executa os códigos de inicialização de cada aplicação específica. Neste caso, django.contrib.auth inclui código que permite você criar uma conta de usuário, django.contrib.sites fornece uma forma fácil de rodar vários sites em um projeto Django, django.contrib.flatpages fornece um modelo de página simples e django.contrib.admin, fornece uma potente interface administrativa. Finalmente, Django termina o setup do banco de dados e instala dados inciais fornecidos. A inserção de novos códigos exige que você execute o comando syncdb. 6.4.3 Acesso aos dados – depois de criar o model, o Django fornece uma interface alto-nível para trabalhar com esses modelo. Execute este comando: python manage.py shell >>>from livros.models import Editor >>>p1=Editor(nome='sergio', endereco='av brasil, 12', cidade='PP', estado='SP', site='www.sergio.com') #Criar um objeto e instanciá-lo passando os valores >>>p1.save() # método para salvar o objeto(Django executa um SQL INSERT) >>>editor_list=Editor.objects.all() #recupera objetos(Django executa SQL SELECT) >>>editor_list [<Editor: Editor object>] >>>p1.id 1L >>>print p1.nome sergio >>>p1.save() >>>p1.nome='marcos' >>>p1.save() >>>editor_list=Editor.objects.all() >>>editor_list [<Editor: Editor object>, <Editor: Editor object>] >>> for x in editor_list: print x.nome … sergio marcos >>>Editor.objects.filter(nome='marcos') #seleciona(SELECT ..FROM ..WHERE) [Editor: marcos] >>>Editor.objects.get(nome='sergio) # recupera um único objeto
  35. 35. >>>Editor.objects.order_by('nome') # ordena dados (SELECT....ORDER BY...) >>>Editor.objects.filter(cidade=”PP”).order_by(“-nome”) #filtrando e ordenando # (SELECT...WHERE ..ORDER BY..) >>>Editor.objects.all()[10] #fixa número de linhas mostrada #(SELECT ….LIMIT 10;) >>>p=Editor.objects.get(nome='sergio') >>>p.delete() #apaga linha da tabela >>>p=Editor.objects.all() >>>p.delete() #apaga um volume de dados todos dados 6.4.4 Mostrando strings do objeto – você pode adicionar comportamento diferente ao modelo. Um modelo Django descreve mais do que um layout da tabela, ele descreve a funcionalidade do objeto. Modifique o arquivo models.py(exemplo a seguir) diretório /meu_site/livros e veja como um modelo pode mostrar a si mesmo from django.db import models class Editor(models.Model): nome = models.CharField(max_length=30) endereco = models.CharField(max_length=50) cidade = models.CharField(max_length=30) estado = models.CharField(max_length=2) site = models.URLField() def __str__(self): return self.nome class Autor(models.Model): nome = models.CharField(max_length=40) email = models.EmailField() foto = models.ImageField(upload_to='/tmp') def __str__(self): return '%s %s' % (self.nome, self.email) class Livro(models.Model): titulo = models.CharField(max_length=100) autores = models.ManyToManyField(Autor) editor = models.ForeignKey(Editor) data_publicacao = models.DateField() def __str__(self): return self.titulo Faça os mesmos testes do item 6.4.3 e veja o que ocorre. 6.4.5 Ordenando objetos – o Django permite você ordenar objetos de um campo em particular evitando ter que ordená-lo toda vez que consultar o campo.
  36. 36. class Editor(models.Model): nome = models.CharField(max_length=30) endereco = models.CharField(max_length=50) cidade = models.CharField(max_length=30) estado = models.CharField(max_length=2) site = models.URLField() def __str__(self): return self.nome class Meta: # esta classe determina a ordenação ordering = [“nome”] 6.4.6 Modificando um esquema de banco de dados – o comando syncdb simplesmente cria tabelas que não existem no banco de dados, ele não atualiza o banco de dados ou deleta modelos. As mudanças de campos devem ser feitas manualmente. Devemos ter em mente que: ▪ o Django vai reclamar em tempo de execução a falta de um campo de dados; ▪ o Django não verifica se alguns campos não foram definidos no modelo; ▪ o Django não cuida se uma tabela não estiver no modelo. 6.4.6.1 Adicionando campos – ao adicionar um campo em uma tabela em produção o truque é tirar vantagem do fato do Django não verificar as tabelas que não estão no modelo. • Adicione o campo a tabela (use o comando SQL: ALTER TABLE); • Altere seu modelo adicionando o campo: num_paginas class Livro(models.Model): titulo = models.CharField(max_length=100) autores = models.ManyToManyField(Autor) editor = models.ForeignKey(Editor) data_publicacao = models.DateField() num_paginas=models.IntegerField(blank=True, null=True) #nao esqueca de # definir valor do campo para não dar erro(blank=True,null=True). def __str__(self): return self.titulo • Reinicie o servidor Web para a mudança ser feita; • Se você executar o comando manage.py sqlall livros voce verá o comando CREATE TABLE e a mudança efetuada; • Execute os comandos abaixo para verificar se não tem erros: python manage.py shell >>>from meu_site.livros.models import Livro >>>Livro.objects.all() [:5]
  37. 37. 6.4.6.2 Removendo campos – basta removê-lo do modelo e reiniciar o servidor. Depois basta acessar o banco de dados e usando o comando ALTER TABLE remover a coluna. Para campo muitos-para-muitos remova o campo do modelo e depois a tabela. Sempre remova o modelo, reinicie o servidor e depois remova o campo ou a tabela. 7. A administração de site do Django – a administração é parte essencial da infra- estrutura e permite adicionar, editar e apagar o conteúdo do site. O único problema da interface de administração é a construção dela, que envolve autenticação de usuários, manipulação de dados, visualização de dados e validação de dados. No Django este problema não existe, porque ele possui uma interface automática de administração de dados. Usando metadados em seu modelo, esta interface fornece uma potente e produtiva forma de administração de dados que pode ser usada imediatamente. 7.1 Usando a interface – como nem todos precisam desta interface, ela não é disponibilizada imediatamente, é necessário então executar alguns passos para habilitá-la. ◦ Adicionando Metadados para seu modelo – você deve marcar qual modelo necessita ter interface de administração. class Livro(models.Model): titulo = models.CharField(max_length=100) autores = models.ManyToManyField(Autor) editor = models.ForeignKey(Editor) data_publicacao = models.DateField() num_paginas=models.IntegerField(blank=True, null=True) #nao esqueca de # definir valor do campo para não dar erro(blank=True,null=True). def __str__(self): return self.titulo def Admin: # adicione esta classe no modelo pass # significa que a classe está vazia # faça isso para a classe Autor e Editor no seu modelo. ◦ Instalando a aplicação Admin – para fazer isto adicione “django.contrib.admin” no INSTALLED_APPS no arquivo de settings.py; ◦ Retire o comentário das linhas: 'django.contrib.sessions', 'django.contrib.auth' , 'django.contrib.contenttypes' , todas as linhas da MIDDLEWARE_CLASSES e apague a linha TEMPLATE_CONTEXT_PROCESSOR; ◦ Execute python manage.py syncdb, este comando adiciona tabelas extras para gerenciamento dos dados e solicita a criação de um super-usuário para
  38. 38. administrar ◦ Adicione a URL em urls.py. from django.conf.urls.default import * #tire o comentario das linhas from django.contrib import admin admin.autodiscover() urlpatterns=patterns('', (r'^admin/(.*)', admin.site.root), ….... ) ◦ Digite no diretório livros o arquivo admin.py: from meu_site.livros.models import * from django.contrib import admin admin.site.register(Autor) admin.site.register(Editor) admin.site.register(Livro) ◦ Execute: python manage.py runserver e depois vá em http://127.0.0.1:8000/ admin/ e veja o que acontece.
  39. 39. Veja também que a interface admin valida as entradas de dados, e que ao lado da administração do site temos um log das Ações Recentes. Também conseguirmos definir usuários e que ações eles podem executar no sistema. Quando um objeto existente é deletado, a interface exige que você confirme a alteração 7.2 Customizando a Interface de Administração – você pode definir a forma de ver a interface de administração e o comportamento dela de inúmeras maneiras. Já vimos que o simples fato de inserir uma função __str__ na classe de models modificou a forma de retorno do objeto, usando esta idéia podemos facilmente adicionar formas de visualizar, buscar e filtrar as funções para esta interface. Modifique a classe Livros do arquivo admin.py como segue. from meu_site.livros.models import * from django.contrib import admin admin.site.register(Autor) admin.site.register(Editor) class LivroAdmin(admin.ModelAdmin): list_display = ('titulo','editor','data_publicacao') list_filter = ('editor','data_publicacao') ordering = ('-data_publicacao',) search_fields =('titulo',) admin.site.register(Livro,LivroAdmin) Antes:
  40. 40. Colocar __str__ no modelo na classe Livros, retorna o TÍTULO DO LIVRO. Veja como ficou a página de edição:
  41. 41. Se aparecer erro quando você modificar a apresentação, modifique o banco de dados executando: python manage.py sqlall livros e python manage.py syncdb Vamos agora inserir a linha sinalizada a seguir e veja como a interface de entrada de dados ficou: from meu_site.livros.models import * from django.contrib import admin admin.site.register(Autor) admin.site.register(Editor) class LivroAdmin(admin.ModelAdmin): fields = ['titulo','data_publicacao','editor'] # fieldsets= [ # (None, {'fields':['titulo']}), # ('Edição', {'fields':['data_publicacao','editor']}),] list_display = ('titulo','editor','data_publicacao') list_filter = ('editor','data_publicacao') ordering = ('-data_publicacao',) search_fields =('titulo',) admin.site.register(Livro,LivroAdmin)
  42. 42. Apenas aparecem os dados que relacionamos e na ordem desejada. Substitua a linha em itálico pelas três linhas comentadas e veja o que acontece. Customizando o nome que aparece na tela de administração - Para fazer isto basta entrar no diretório do Django ..django/contrib/admin/templates e copie o arquivo admin/base_site.html para o diretório do seu site na pasta templates no diretório admin e basta alterar o html. Altere o diretório TEMPLATE_DIRS em settings.py para este diretório.
  43. 43. Mudei o nome para Sérgio administração. 8. Visualizando os dados cadastrados no banco de dados – ao fazermos uma aplicação várias páginas são necessárias e cada uma delas tem um modelo(template). Por exemplo, as várias vistas de um Blog: temos a página principal, página de detalhe, as páginas mostrando os textos por ordem cronológica e a página de comentário. Cada vista é representado por uma função Python. 8.1 Projetando as várias vistas – primeiro devemos desenhar a estrutura das URLs, criando um módulo Python chamado URLconf. Quando um usuário requisita uma página, o sistema Django olha o ROOT_URLCONF e localiza uma string com pontos Python(exemplo: meu_site.home). Após isto carrega-se o módulo e verifica a variável chamada urlpatterns (tupla do tipo: (expressao, chamada função [, opção]). O Django começa a verificar a partir da primeira expressão regular e desce a lista comparando a requisição URL com a expressão regular, até encontrar um item. Ao encontrar o item o Django chama a função, utilizando um objeto HttpRequest como primeiro argumento e outras informações, é assim que o sistema localiza qual função irá atender está requisição. Para gerar a variável ROOT_URLCONF que está localizada em settings.py, basta iniciar o projeto com python django-admin.py startproject meu_site que vai criar o arquivo urls.py . ROOT_URLCONF = 'meu_site.urls' # é setada automaticamente 8.2 Escrevendo a primeira vista (view) com uso de banco de dados – já fizemos chamada as views sem usar models (modêlo de dados), vamos agora acessar nossos dados que estão numa base e mostrá-los no navegador através de uma URL. Edite o arquivo urls.py e coloque as informações: from django.conf.urls.default import * from meu_site.views import *
  44. 44. 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'^livros/$','meu_site.livros.views.lista_livros'), ) Digite esta vista em meu_site/livros/views.py: #views.py from django.shortcuts import render_to_response from meu_site.livros.models import * def lista_livros(request): livros=Livro.objects.all() return render_to_response('livros.html',locals()) Digite este template em meu_site/livros/templates/livros.html: <!-- arquivo: livros.html → {%extends "base.html" %} {%block titulo %}Relaçao de Livros{%endblock %} {%block titulo1%}Relação de Livros{%endblock%} {%block conteudo%} <table border> <tr> <td>Código</td> <td>Titulo</td> <td>Data Publicação</td> <td>Editor</td> {% for x in livros %} <tr> <td>{{x.id}}</td>
  45. 45. <td> {{x.titulo}}</td> <td> {{x.data_publicacao}} </td> <td> {{x.editor}}</td> </tr> {% endfor %} </table border> {%endblock%} Os comandos table border, tr e td são usados para gerar uma tabela na tela. Digite o comando na tela do prompt de comando: python manage.py runserver Agora digite no navegador a URL: http://localhost:8000/livros/ Veja a tela do browser: *************Utilize o material até aqui, dentro de 30 dias estará disponibilizado o restante com as correções devidas**************** 9. Disponibilizando um CMS(Sistema de gerenciamento de conteúdo) – em Django as aplicações contrib são projetadas para adicionar características que diminuem a quantidade e a repetição de código. Um CMS é um bom exemplo disso: admin e flatpages. O admin já é conhecido por nós e o flatpages (páginas planas)
  46. 46. veremos a seguir. O flatpages, django.contrib.flatpages, fornece um modelo para uma página bem simples, que contém título, conteúdo e poucas configurações e o admin, django.contrib.admin, fornece uma potente interface administrativa que trabalha com os modelos de dados do Django, que permite a criação quase que instantânea de uma interface administrativa do site. Primeiro devemos adicionar em INSTALLED_APPS as aplicações 'django.contrib.admin' e 'django.contrib.flatpages'. Uma vez que já adicionamos o admin anteriormente basta agora inserir apenas o flatpages. INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.flatpages', # inserir esta linha 'meu_site.livros', ) Agora execute o comando: python manage.py syncdb. Este comando cria tabelas no banco de dados para esta aplicação. Agora abra o arquivo urls.py em seu projeto meu_site e digite: (r'',include('django.contrib.flatpages.urls')), e tire o comentário da linha (r'^admin/(.*)', admin.site.root), já foi feito anteriormente.
  47. 47. Execute a interface admin e veja as Flatpages que agora poderão ser utilizadas. Cada item listado nesta página corresponde a um modelo de dados de uma aplicação instalada. A aplicação Auth fornece modelo para grupos e usuários; a aplicação Sites oferece um modelo para representar um web site. Na coluna ações recentes temos listada todas as ações efetuadas no site. Adicione uma flatpage e no lado direito superior clique em Ver no site. Um erro será relatado: Not Found. Para que o Django exiba esta página abra urls.py e digite a linha: (r' ', include('django.contrib.flatpages.urls')), - note que a string vazia (' ') permite que o Django encontre qualquer flatpages que você digite. Agora teste novamente e veja que outro erro apareceu: TemplateDoesNotExist – execption value: flatpages/default.html. Este erro ocorre porque não temos a página para visualização da flatpage. Dentro do diretório templates crie um sub-diretório chamado flatpages/ e dentro dele insira o arquivo default.py. #default.py <html> <head> <title>{{ flatpage.title }}</title> </head>
  48. 48. <body> <h1>{{ flatpage.title }}</h1> {{ flatpage.content }} </body> </html> Veja que para acessar esta página temos que ver TEMPLATE_DIRS em settings.py se este sub-diretório está definido, como já definimos ele anteriormente podemos agora visualizar as flatpages cadastradas. No arquivo acima temos duas variáveis flatpage.title e flatpage.content cujo valor é o objeto FlatPage, uma instância do modelo de dados das flatpages. Agora sim temos um simples CMS e podemos definir várias páginas e seus títulos em qual URL quisermos , exceto a admin. 10.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/

×