Professional Documents
Culture Documents
Joinville
2007/1
Esse trabalho ser apresentado ao Instituto Superior Tupy como requisito parcial para a obteno
de grau de bacharel em Sistemas de Informao,
sob orientao do Professor MSc. Marco Andr
Lopes Mendes.
Joinville
2007/1
THOMAZ, FABIO EDUARDO ESTUDO DO FRAMEWORK DJANGO E DA SUA UTILIZAO NO DESENVOLVIMENTO DE UMA APLICAO WEB PARA O CONTROLE
DE ALOCAO DOS PROFESSORES DO INSTITUTO SUPERIOR TUPY
Joinville: SOCIESC, 2007/1.
AGRADECIMENTOS
Agradeo a Deus por ter me dado foras para chegar at aqui. Agradeo a toda a
minha famlia pelo incentivo constante minha formao acadmica. Agradeo ainda minha
noiva, Muriel Mller, que soube compreender minha ausncia durante o desenvolvimento deste
trabalho e me motivou a seguir em frente nos momentos em que pensei em desistir. Aos meus
tios, Joo Paulo Gesser e Jos Srgio Gesser, que me deram a oportunidade de iniciar a minha
vida profissional. Datasul Tecnologia, por ter me dado um um perodo de frias que auxiliou
na concluso deste trabalho. Aos meus amigos, que sempre mostraram-se dispostos a me
ajudar quando precisei. A todos os professores que j tive, que souberam compartilhar suas
experincias e conhecimentos comigo e com todos os outros alunos. Ao pessoal do grupo
Django Brasil, que ajudaram-me a dirimir dvidas e compartilharam as suas experincias com
o Django.
Aos professores Marco Andr Lopes Mendes, Mehran Misaghi, Sandro Jos de Oliveira
e Eduardo da Silva, que souberam cobrar, instruir, corrigir e motivar o desenvolvimento deste
trabalho.
A todos, muito obrigado.
RESUMO
ABSTRACT
Nowadays, companies and independent developers are always looking for ways to reduce the
time of development and raise the quality of their software applications. They look for tools that
help the development process. This paper will present the Django Framework, whose purpose is
to meet those needs of decreasing the time of development and increase the quality of application. This paper will present the main features of the framework and some preliminary concepts
as the MVC methodology, Python language, HTML, JavaScript and CSS. An application will also
be developed to control teacher allocation at a school, as a case study of the use of Django
Framework.
Keywords: Django, Python, Programming, Web
Lista de Figuras
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
. . . . . . . . . . . . . . . . . . . . 22
. . . . . . . . . . . . . . . . . . . . . . . 23
. . . . . . . . . . . . . . . . . . . . . . 24
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
. . . . . . 27
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
. . . . . . . . . . . . . . . . . . . . . . . . . . . 28
. . . . . . . . . . . . . . . . . . . . . . . . . . . 30
. . . . . . . . . . . . . . . . . . 31
. . . . . . . . . . . . . . . . . . . . 31
Figura 14 - Tecnologias utilizadas por uma aplicao Web desenvolvida com Django
Figura 15 - Execuo do script de instalao do Django
. . 32
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
. . . . . . . . . . . . . . . . . . . . . . . 34
. . . . . . . . . . . . . . . . . . . . . . . . . . 35
. . . . . . . . . . . . . . . . . . . . . . . . 36
. . . . . . . . . . . . . . . . . 36
. . . . 39
. . . . . . . . . . . . 40
. . . . . . . . . . . . . . . . 41
Figura 23 - Verificao dos comandos SQL gerados com base nos modelos de dados
Figura 24 - Resultado da execuo do script manage.py com a opo sqlall
. 41
. . . . . . . . . . . 42
Figura 25 - Criao das tabelas no banco de dados de acordo com os modelos de dados
Figura 26 - Definio do modelo Titulao e relacionamento com o modelo Professor
42
. . 43
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
. . . . . . . . . . . . . . . . . . . . . . . . . 47
. . . . . . . 48
. . . . . . . 48
. . . . . . . . . . . . . . . . . . . . . 49
. . . . . . . . . . . . . . 52
. . . . . . . . . . . . . . . . . . . . . . 53
. . . . . . . . . . . . . 53
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
. . . . . . . . . . . . . . . . 54
. . . . . . . . . . . . . . . . . . 55
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
. . . . . 56
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
. . . 49
. . . . . . . . . . . . . . . 58
. . . . . . . . . . . . . . . . . . . 59
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
. . . . . . . . . . . . . . . . . . . . . . . . . . . 59
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
. . . . . . . . . . . . . . . . . . . 62
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
. . . . . . . . . . . . . . . . . . . . . . . 63
. . . . . . . . . . . . . . . . . . . . . . . . . . . 63
. . . . . . . . . . . . . . . . . . . . . . . . . . . 64
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
. . . . . . . . . . . . . . . . . . . 66
. . . . . . . . . . . . . . 67
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
. . . . 69
. . . . . . . . . . . . . . . . . . . . . 72
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Lista de Tabelas
. . . . . . . . . . . . . . . . . . 40
. . . . . . . . . . . . . . . . . 43
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
SUMRIO
1 INTRODUO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
2 CONCEITOS PRELIMINARES
18
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
18
20
21
. . . . . . . . . . . . . . . . . . . .
22
. . . . . . . . . . . . . . . . . . . . . . . . .
25
. . . . . . . . . . . . . . . . . .
26
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
29
29
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
. .
31
3 DJANGO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
33
3.2 CARACTERSTICAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
34
34
37
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
39
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
. . . . . . . . . . . . . . . . . . . . . . . . .
45
47
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51
51
. . . . . . . . . . . . . . . . . . . . . . .
56
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
3.10TEMPLATES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
3.11MANIPULAO DE FORMULRIOS . . . . . . . . . . . . . . . . . . . . . . . . .
65
67
3.9.1 AJAX
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . .
70
70
4.2 REQUISITOS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
71
4.4 MODELAGEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
71
72
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
75
5 CONCLUSO
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
REFERNCIAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
80
. . . . . . . .
82
. . . . . . . . .
83
. . . . . . . . . . . . . . . . . . . . . .
84
85
89
92
. . . . . . . . . . . . . . . . . . . . .
16
INTRODUO
H alguns anos a Internet tem sido o foco na estratgia das empresas em busca do
crescimento e da consolidao dos seus negcios. Com isso, a demanda por profissionais com
o conhecimento necessrio para o desenvolvimento de solues Web continua crescendo.
Em funo dessa demanda, necessrio que desenvolvedores e profissionais que pretendem entrar no mercado de desenvolvimento conheam um vasto conjunto de linguagens
de programao, ferramentas e metodologias para o desenvolvimento de aplicaes. Porm,
devido dificuldade de encontrar materiais na lngua portuguesa sobre determinada tecnologia, muitos acabam perdendo a oportunidade de adquirir novos conhecimentos, pela falta de
conhecimentos em outras lnguas, dentre elas e principalmente a lngua inglesa.
Uma das maiores dificuldades das empresas de desenvolvimento de aplicaes atender aos prazos dos clientes, que so cada vez menores. Para conseguir alcanar os prazos,
muitos acabam baixando a qualidade de suas aplicaes, fazendo menos testes do que o necessrio, implementando funcionalidades importantes sem um estudo adequado e deixando de
documentar o cdigo fonte desenvolvido. Os problemas causados por estas escolhas so o
aumento no nmero de erros na aplicao, insatisfao do cliente, dificuldade de manuteno
e retrabalho.
Na tentativa de resolver esses problemas, so utilizados frameworks de desenvolvimento
de aplicaes. Os frameworks fornecem uma estrutura para que o desenvolvimento se torne
mais rpido, organizado e para que o produto desenvolvido possua qualidade e fcil manuteno. Um framework procura reunir funcionalidades comuns a vrias aplicaes, de forma que
o desenvolvedor codifique pequenas partes, que pertecem ao domnio de problema especfico
da aplicao.
O Django um framework de alto nvel, desenvolvido na linguagem Python, e tem por
objetivo agilizar e facilitar o desenvolvimento de aplicaes Web, sem perder a qualidade e a
organizao do cdigo da aplicao. Esse framework automatiza algumas tarefas que podem
complicar e confundir a linha de raciocnio de um iniciante, alm de estruturar a aplicao em
camadas, conforme a metodologia Model, View, Controller conhecida como MVC.
O objetivo deste trabalho realizar um estudo do framework Django, servindo como
referncia no seu aprendizado, reunindo as suas principais funcionalidades e detalhando-as
com exemplos e com o desenvolvimento de uma aplicao exemplo. A aplicao escolhida ser
utilizada para controlar a alocao dos professores de uma instituio de ensino.
17
As atividades necessrias para a construo deste trabalho foram desenvolvidas no sistema operacional Linux, com o kernel verso 2.6.17.13. A distribuio utilizada foi o Slackware
Linux, verso 10.2. Para o desenvolvimento dos exemplos e da aplicao do estudo de caso,
foi utilizada a reviso 5318 da verso de desenvolvimento do framework Django e a linguagem
Python, verso 2.4.1. O navegador Internet utilizado para testar os exemplos e a aplicao desenvolvida foi o Firefox, verso 2.0.0.4. O trabalho foi escrito utilizando LATEX com o editor Kile,
verso 1.9.3. Todas as imagens e cdigos disponveis no trabalho que no possuem referncia
foram desenvolvidos pelo autor deste trabalho. Para a criao das imagens, foram utilizados
o Microsoft Visio 2003, no sistema operacional Windows XP, e o editor de imagens GIMP. Os
cdigos dos exemplos e da aplicao foram escritos com o editor de textos Kate, verso 2.5.4.
Este trabalho foi dividido da seguinte forma:
No captulo 2 sero abordados conceitos preliminares, nos quais se incluem a arquitetura de uma aplicao Web, as tecnologias envolvidas no processo de desenvolvimento de uma
aplicao Web, as aplicaes necessrias para o funcionamento de uma aplicao desenvolvida com o framework Django e como estes componentes funcionam em conjunto.
No captulo 3 sero detalhadas as principais caractersticas e funcionalidades do framework Django, desde a sua instalao at o desenvolvimento de uma aplicao Web. Sero
utilizados exemplos que, ao final, faro parte da aplicao desenvolvida no estudo de caso.
No captulo 4 ser apresentado o estudo de caso do desenvolvimento de uma aplicao
para a alocao de professores em uma instituio de ensino. Sero apresentados os requisitos da aplicao, a modelagem das tabelas identificadas e a aplicao desenvolvida com o
framework Django.
Finalizando o trabalho, sero apresentadas as concluses, incluindo as principais vantagens e as dificuldades encontradas durante o desenvolvimento da aplicao com o framework
Django. Sero apresentadas tambm algumas sugestes para trabalhos futuros.
18
CONCEITOS PRELIMINARES
Este captulo apresenta a arquitetura de uma aplicao Web, as tecnologias envolvidas no processo de desenvolvimento de uma aplicao Web, as aplicaes necessrias para o
funcionamento de uma aplicao desenvolvida com o framework Django e como esses componentes funcionam em conjunto.
2.1
19
II. as requisies enviadas pelo usurio atravs da interface so tratadas por um servidor
Web;
III. um grande nmero de usurios pode acessar a aplicao Web ao mesmo tempo;
IV. a quantidade de acessos aplicao Web pode mudar completamente entre um dia e
outro;
V. os usurios querem acesso na base de "24/7/365", ou seja, 24 horas por dia, 7 dias
por semana e 365 dias por ano, devido a diferena de fuso horrio entre os usurios da
aplicao, que podem estar em qualquer lugar do mundo;
VI. a evoluo da aplicao Web no se d por meio de verses planejadas e cronologicamente espaadas, e sim continuamente;
VII. necessidade de colocao no mercado rapidamente;
VIII. dificuldade em limitar a populao de usurios que podem ter acesso a uma aplicao
Web, sendo necessria a utilizao de fortes medidas de segurana em toda a infraestrutura que apia uma aplicao Web;
IX. a esttica possui grande influncia no sucesso da aplicao.
20
2.2
A MVC, sigla para os termo em ingls Model, View, Controller, significa Modelo, Visualizao e Controlador. um padro de desenvolvimento que sugere a separao do cdigo
fonte da aplicao em trs partes, tambm conhecidas por camadas, onde cada camada responsvel por tarefas especficas, facilitando o desenvolvimento e a manuteno do cdigo da
aplicao.
21
2.3
I. maximizao do re-uso;
II. diminuio do tempo de desenvolvimento;
III. reduo de custos;
IV. estabilizao do cdigo, devido ao uso em vrias aplicaes;
V. desenvolvimento voltado a adicionar valor aplicao;
VI. melhor consistncia e compatibilidade entre aplicaes;
VII. diminuio e facilidade de manuteno.
22
2.4
# coding : l a t i n 1
def i s P a l i n d r o m o ( l i n h a ) :
r e t u r n ( l i n h a == l i n h a [ : : 1 ] )
p r i n t "VERIFICAO DE PALNDROMOS"
i f isPalindromo ( l i n h a ) :
9
10
11
p r i n t " palndromo"
else :
p r i n t "No palndromo"
23
O cdigo do programa contm apenas o que o programa deve fazer, ou seja, solicitar a
entrada do usurio, remover os espaos em branco, passar todo o texto para letra minscula e
realizar a comparao do texto informado com o texto invertido. O mesmo programa, escrito na
linguagem C++, ficaria conforme a figura 4.
using namespace s t d ;
bool i s P a l i n d r o m o ( s t r i n g l i n h a ) {
s t r i n g : : size_type index ;
string auxiliar ;
f o r ( i n t i = 0 ; i < l i n h a . l e n g t h ( ) ; i ++) {
10
11
12
while ( i n d e x ! = s t r i n g : : npos ) {
13
l i n h a . r e p l a c e ( index , 1 , "" ) ;
14
15
16
auxiliar = linha ;
17
r e v e r s e ( a u x i l i a r . begin ( ) , a u x i l i a r . end ( ) ) ;
18
r e t u r n ( a u x i l i a r == l i n h a ) ;
19
20
i n t main ( ) {
21
char i n p u t [ 1 0 0 ] ;
22
string linha ;
23
24
25
26
linha = input ;
27
i f ( isPalindromo ( l i n h a ) ) {
28
29
} else {
30
31
32
return 0;
33
24
A linguagem C++ requer que o programa esteja dentro de uma funo. Alm disso,
necessria a incluso das bibliotecas iostream e string. As chaves e os ponto-e-vrgula so
parte da liguagem. Na linguagem Java, todo cdigo deve estar dentro de uma classe, conforme
a figura 5.
import j a v a . i o . BufferedReader ;
import j a v a . i o . IOException ;
import j a v a . i o . InputStreamReader ;
s t a t i c boolean i s P a l i n d r o m o ( S t r i n g l i n h a ) {
StringBuffer auxiliar ;
a u x i l i a r = new S t r i n g B u f f e r ( l i n h a ) ;
r e t u r n l i n h a . equals ( a u x i l i a r . r e v e r s e ( ) . t o S t r i n g ( ) ) ;
10
11
12
BufferedReader i n p u t ;
13
14
String linha ;
15
16
try {
17
18
l i n h a = i n p u t . readLine ( ) ;
19
i f ( Palindromo . i s P a l i n d r o m o ( l i n h a ) ) {
20
21
} else {
22
23
24
input . close ( ) ;
25
} catch ( IOException e ) {
26
System . e r r . p r i n t l n ( e . getMessage ( ) ) ;
27
28
29
}
}
A linguagem Python permite a utilizao de funes e classes, mas no fora o programador a utiliz-las (ZELLE, 1999).
25
Outra caracterstica que torna a linguagem Python mais didtica a tipagem dinmica
das variveis. O programador no obrigado a definir o tipo da varivel antes de utiliz-la.
A prpria linguagem entende o tipo do valor que o programador deseja associar varivel e
determina o seu tipo, dinamicamente.
De acordo com (DEITEL et al., 2002), a linguagem Python oferece uma srie de vantagens,
citadas seguir:
2.5
Uma pgina Web composta basicamente por texto e uma srie de marcaes (tambm
conhecidas como tags) da linguagem HTML, que so utilizadas para estruturar e formatar o contedo da pgina e criar ligaes entre vrias pginas diferentes. A sigla HTML um acrnimo
para Hypertext Markup Language, que significa Linguagem de Marcao de Hipertexto. Os
elementos da linguagem HTML so definidos pelo W3C Consortium, um instituto responsvel
por manter os padres de algumas das tecnologias utilizadas no desenvolvimento de aplicaes Web. Quando uma pgina Web carregada por um navegador Internet, o cdigo HTML
da pgina interpretado e o contedo exibido ao usurio, de acordo com as marcaes de
formatao definidas no cdigo.
A figura 6 mostra o cdigo-fonte com as marcaes HTML.
<html>
<body>
< / body>
< / html>
26
2.6
Conforme visto na seo anterior, a linguagem HTML no possui outra funo alm de
formatar o contedo das pginas Web e criar as ligaes entre as pginas. No ano de 1994, a
empresa Netscape sentiu a necessidade de processar dados na prpria pgina HTML, de forma
que no fosse necessrio o envio de uma requisio ao servidor para realizar operaes que
poderiam ser realizadas no prprio navegador do usurio. Um exemplo muito comum dentre
estas operaes a validao dos dados de um formulrio antes de envi-lo ao servidor. Partindo desta necessidade, a Netscape criou a linguagem LiveScript e adicionou o interpretador
no seu navegador, o Netscape Navigator. Em 1995, j com a participao da empresa Sun
Microsystems no projeto, o nome da linguagem foi mudado para JavaScript (GALDINO, 2006).
A figura 8 mostra um exemplo de cdigo JavaScript utilizado para vincular o clique de
um boto definido em uma pgina HTML a uma funo definida na linguagem JavaScript.
27
< s c r i p t type="text/javascript">
f u n c t i o n my_onclick ( ) {
. . .
< / script>
< / button>
Segundo (GALDINO, 2006), a linguagem JavaScript foi criada para pequenos processamentos. Por este motivo, foi muito utilizada para acrescentar recursos simples pgina, s vezes banais. Esse uso o que a faz ser lembrada como uma extenso do HTML e no como uma
linguagem de fato. Porm, segundo o mesmo autor, a JavaScript uma linguagem completa
e poderosa, com as limitaes que o meio exige. A sua principal utilizao est relacionada
manipulao dos elementos da pgina HTML.
Um dos maiores problemas na utilizao da linguagem JavaScript est relacionado aos
diferentes interpretadores existentes. Alguns navegadores possuem comandos JavaScript especficos, fazendo com que uma pgina desenvolvida utilizando estes comandos deixe de funcionar corretamente em um navegador diferente.
Visando diminuir este problema, a European Computer Manufacturers Association (ECMA)
criou a especificao ECMAScript, para padronizar a linguagem JavaScript. Os scripts criados
de acordo com os padres definidos no ECMAScript devem funcionar de forma idntica em
qualquer navegador que implemente estas especificaes.
2.7
CSS a sigla para Cascading Style Sheets, que significa Folha de Estilos em Cascata.
uma linguagem para estilos que define a disposio de documentos HTML (SILVA, 2007).
Embora seja possvel definir cores, fontes, posicionamento, e outros atributos relacionados com o estilo do documento utilizando a linguagem HTML, a utilizao do CSS proporciona
ao desenvolvedor vrias facilidades, centralizando todas as definies relacionadas ao estilo do
28
documento. A correta utilizao do CSS permite que o desenvolvedor mude o estilo de uma
aplicao Web por completo em poucos minutos.
A figuras 9 mostra um exemplo de um arquivo CSS.
body {
backgroundc o l o r : #FF0000 ;
2
3
1
2
<html>
<head>
< / head>
<body>
7
8
9
29
2.8
2.8.1
2.9
1999). O HTTP, sigla para o termo Hypertext Transfer Protocol, um protocolo de nvel
de aplicao utilizado para enviar e receber dados na Internet. A sua ltima verso foi definida
pela RFC 2616, disponvel em (THE INTERNET SOCIETY, 1999).
O Apache um servidor Web atualmente mantido por um grupo de voluntrios espalhados pelo mundo, que utilizam a Internet para se comunicar, planejar e desenvolver o servidor e
toda a documentao relacionada (APACHE SOFTWARE FOUNDATION, 2007). Atualmente, o servidor Web mais utilizado no mundo, possuindo cerca de 58% do mercado de servidores Web,
de acordo com os dados da Netcraft (NETCRAFT, 2007).
30
Dentre as suas principais caractersticas, se destaca o fato de ser uma aplicao multiplataforma, possuir um bom desempenho, robustez e flexibilidade (BAREINBOIM, 2006). A flexibilidade do Apache permite que sejam desenvolvidos mdulos para tratar de requisies que
necessitam de processamento por uma tecnologia externa, como aplicaes escritas nas linguagens PHP, Python, Ruby, entre outras.
Para que o Apache possa ser o servidor Web de uma aplicao desenvolvida com o
framework Django, necessria a utilizao do mdulo mod_python, explicado a seguir.
2.9.1
Mdulo Mod_Python
Existem trs formas de se executar um cdigo Python atravs do Apache. A primeira
atravs do modelo CGI, sigla para o termo Commom Gateway Interface, onde cada requisio
inicializa um processo do interpretador Python e redireciona a sua sada padro para o navegador do usurio. A segunda atravs do redirecionamento da requisio para um outro servidor
Web, que executado em paralelo ao Apache. A terceira e melhor forma de executar um cdigo
Python atravs do Apache utilizando o mdulo mod_python (TRUBETSKOY, 2003).
O mod_python um mdulo para o servidor Web Apache que permite a comunicao do
Apache com o interpretador da linguagem Python. Quando o Apache iniciado, uma instncia
do interpretador Python alocado na memria do servidor, fazendo com que a cada execuo
de um cdigo Python no seja necessrio inicializar o interpretador. Este modelo faz com que
seja aproveitada a habilidade do Apache em tratar as requisies, deixando para o interpretador
Python somente a execuo do cdigo necessrio.
Testes de desempenho constataram a vantagem da utilizao do mod_python com relao ao modelo CGI. A figura 11 mostra os resultados de 1000 execues de um programa
atravs do modelo CGI, utilizando 10 conexes:
77.723 [ms]
31
5.808 [ms]
A figura 13 apresenta um grfico comparativo do desempenho na execuo das requisies utilizando CGI e mod_python.
2.10
Todas as tecnologias vistas neste captulo so importantes para entender o funcionamento de uma aplicao Web desenvolvida com o framework Django. A figura 14 mostra como
32
essas tecnologias relacionam-se durante a execuo de uma aplicao Web desenvolvida com
Django.
Figura 14: Tecnologias utilizadas por uma aplicao Web desenvolvida com Django
33
DJANGO
3.1
VISO GERAL
3.2
CARACTERSTICAS
O framework Django possui uma srie de caractersticas que o destacam no que diz
respeito ao desenvolvimento de aplicaes Web:
34
3.3
A instalao cria o diretrio Django abaixo do diretrio site-packages, localizado no diretrio de instalao do Python, que pode variar de acordo com o sistema operacional utilizado.
A referncia oficial para a instalao do framework Django pode ser encontrada em
(LAWRENCE JOURNAL-WORLD, 2007).
3.4
Para iniciar o desenvolvimento de uma aplicao web com o framework Django, necessrio criar um projeto utilizando o script django-admin.py com a opo startproject e o nome
do projeto, conforme exemplo abaixo:
35
Este script cria o diretrio do projeto, chamado de piramide, abaixo do diretrio atual.
Caso isto no ocorra, necessrio verificar a instalao do framework Django.
Dentro do diretrio do projeto, so criados os seguintes arquivos:
I. __init__.py: arquivo utilizado pelo Python para identificar que o diretrio atual um pacote;
II. manage.py: arquivo utilizado para a execuo das tarefas do projeto, como uma nova
aplicao ou a sincronizao do projeto com o banco de dados, por exemplo;
III. settings.py: arquivo com as configuraes do projeto;
IV. urls.py: arquivo responsvel pelo mapeamento entre a url solicitada pelo usurio e a view
do projeto responsvel por enviar a resposta requisio.
O Django vem com um servidor Web embutido, bastante til para o processo de aprendizado e de desenvolvimento das aplicaes. Porm, esse servidor no deve ser utilizado em
ambientes de produo, visto que este capaz de atender apenas uma requisio por vez.
Para ambientes de produo, necessrio utilizar um servidor Web capaz de atender mltiplas
requisies, como por exemplo o Apache.
Aps a criao do projeto, possvel executar o servidor Web de desenvolvimento do
Django, atravs do seguinte comando:
36
Para verificar se o Django est funcionando corretamente, necessrio acessar o endereo http://localhost:8000, onde 8000 o nmero da porta que o servidor responde s requisies. Ao acessar este endereo, a seguinte pgina dever ser apresentada, informando que
o Django est funcionando corretamente:
Este script cria o diretrio da aplicao Professores, dentro do projeto piramide. Neste
diretrio, so criados os seguintes arquivos:
I. __init__.py: arquivo utilizado pelo Python para identificar que o diretrio atual um pacote;
II. models.py: arquivo utilizado para a definio dos modelos de dados utilizados pela aplicao;
III. views.py: arquivo utilizado para a definio das views da aplicao, que possuiro o papel
de controller, em uma anlise segundo a metodologia MVC;
37
A definio dos modelos de dados e a utilizao das views sero detalhados mais adiante neste captulo.
A criao do projeto e das suas aplicaes faz com que a estrutura bsica de uma
aplicao Web seja criada. A partir deste momento, necessrio configurar o projeto para,
ento, iniciar a codificao das aplicaes.
3.5
CONFIGURAES DO PROJETO
38
VI. DATABASE_PORT: varivel utilizada para informar a porta para a conexo com o servidor
do banco de dados;
Alm de configurar os parmetros relacionados ao banco da dados, existem outras configuraes importantes para iniciar o desenvolvimento de uma aplicao Web:
I. TIME_ZONE: varivel utilizada para informar ao Django qual o fuso horrio utilizado pelo
projeto. Uma lista com todas as opes possveis pode ser acessada em (POSTGRESQL
GLOBAL DEVELOPMENT GROUP, 2007).
pedar vrias aplicaes Web desenvolvidas com o Django que possuam fusos diferentes.
De acordo com a documentao oficial do projeto, este recurso no est disponvel em
servidores que utilizam o sistema operacional Windows. Nestes casos, esta varivel deve
receber o fuso horrio utilizado pelo sistema operacional;
II. LANGUAGE_CODE: varivel utilizada para informar ao Django o idioma utilizado pelo
projeto;
III. INSTALLED_APPS: varivel utilizada para informar ao Django quais as aplicaes do projeto estaro disponveis. As aplicaes disponveis so informadas em um tupla, objeto
da linguagem Python semelhante a uma lista, porm com a diferena de que ela no pode
ser alterada aps a sua definio, ou seja, imutvel.
A configurao inicial do Django para o projeto utilizado nos exemplos deste trabalho
mostrada na figura 20. As variveis que no so exibidas devem permanecer com os seus
valores iniciais.
39
DATABASE_ENGINE = mysql
DATABASE_NAME = piramide
DATABASE_USER = django
DATABASE_PASSWORD =
DATABASE_HOST =
DATABASE_PORT =
TIME_ZONE = America/Sao_Paulo
LANGUAGE_CODE = pt-br
INSTALLED_APPS = (
django.contrib.auth ,
django.contrib.contenttypes ,
django.contrib.sessions ,
django.contrib.sites ,
piramide.professores
)
3.6
40
A figura 21 mostra a definio do modelo de dados Professor para a aplicao professores, no arquivo models.py:
matricula
nome
endereco
bairro
cidade
uf
10
telefone
11
12
salario
13
O Django possui uma srie de tipos de campos que atendem diversas necessidades
encontradas no desenvolvimento de aplicaes Web. A tabela 1, mostrada a seguir, explica os
tipos de campos utilizados no modelo de dados Professor. Uma lista com todos os tipos de
campos disponveis no Django pode ser encontrada em (LAWRENCE JOURNAL-WORLD, 2007).
Tabela 1: Tipos de campo utilizados no modelo de dados Professor
Tipo de Campo
Aplicao
CharField
EmailField
DecimalField
IntegerField
41
Figura 23: Verificao dos comandos SQL gerados com base nos modelos de dados
O resultado deste comando, com base no modelo definido no arquivo models.py, deve
ser semelhante ao resultado mostrado na figura 24, quando o SGBD utilizado for o MySQL:
42
BEGIN ;
CREATE TABLE p r o f e s s o r e s _ p r o f e s s o r (
b a i r r o varchar ( 5 0 ) NULL,
10
11
12
13
h o r a s _ c o n t r a t o i n t e g e r NOT NULL
14
);
15
COMMIT;
A execuo do script manage.py com as opes validate e sqlall servem apenas para
realizar verificaes, no sendo necessrio execut-los para criar as tabelas. Porm, caso
exista algum problema na definio dos modelos de dados ou nos parmetros de conexo com
o banco de dados, ser possvel identific-lo antes da execuo do comando para a criao das
tabelas.
Para efetivar a criao das tabelas no banco de dados, necessrio executar o script
manage.py com a opo syncdb, conforme exemplo a seguir:
Figura 25: Criao das tabelas no banco de dados de acordo com os modelos de dados
43
pontos
def _ _ s t r _ _ ( s e l f ) :
8
10
return s e l f . descricao
11
matricula
12
nome
13
endereco
14
bairro
15
cidade
16
uf
17
telefone
18
19
salario
20
21
titulacao
Tipo de Relacionamento
ForeignKey
ManyToManyField
OneToOneField
Todos os mtodos de relacionamento devem receber como parmetro o nome do modelo, ou seja, da classe com o qual est sendo feito o relacionamento. Caso o Django no
reconhea o modelo pelo fato de este estar definido aps o modelo que possui o campo relacionado, possvel informar o nome do modelo no formato string como parmetro para o mtodo
de relacionamento, conforme o exemplo mostrado na figura 27.
44
matricula
nome
endereco
bairro
cidade
uf
10
telefone
11
12
salario
13
14
titulacao
16
17
18
pontos
20
def _ _ s t r _ _ ( s e l f ) :
21
return s e l f . descricao
O mtodo __str__() utilizado para retornar a representao string dos objetos que so
instncias da classe onde o mtodo foi definido. O uso deste mtodo ficar mais claro ao longo
deste captulo. Aps cada alterao no arquivo models.py, necessrio aplicar estas alteraes
no banco de dados, atravs do script manage.py, com a opo syncdb.
3.7
45
3.7.1
do modelo de dados representa uma tabela do banco de dados. Logo, uma instncia desta
classe representa um registro no banco de dados.
Para exemplificar a criao de registros, ser utilizado o console interativo da linguagem
Python no projeto Django. Para iniciar o console interativo do projeto, necessrio executar o
script manage.py com a opo shell, conforme exemplo seguir:
Para criar um registro no banco de dados atravs do Django, basta criar uma instncia
da classe que corresponde a tabela em que deseja-se criar o registro, atribuir os valores necessrios aos atributos do objeto e chamar o mtodo save(). Os atributos do objeto so os campos
definidos no modelo de dados. A figura 29 mostra um exemplo de criao de um registro atravs do console interativo do projeto. importante lembrar que para cada modelo de dados, o
Django cria um campo chamado id, que recebe um valor seqencial automaticamente durante
a criao do registro. O exemplo mostra que este campo no possui valor antes da chamada do
mtodo save(). Aps a chamada do mtodo, o registro j est armazenado no banco de dados
e o campo id possui o valor 1.
46
Desta forma, a consulta no banco de dados realizada pelo Django acontece somente na
chamada do mtodo save(), sendo assim necessrio informar os valores para todos os campos
do registro, mesmo que a necessidade seja alterar apenas um. Para contornar este problema,
possvel realizar a busca do registro, alterar somente o campo necessrio e salvar a atualizao. Para buscar o registro em questo, utiliza-se o mtodo get(), passando como parmetro
o campo, a condio e o valor para consulta. Qualquer campo do modelo de dados pode ser
utilizado, juntamente com as condies de consulta que sero vistas ao longo deste captulo.
47
3.7.2
48
print item.descricao
...
Graduado
Mestrado
Doutorado
>>>
Figura 32: Consulta a todos os registros da tabela Titulacao com o mtodo all()
Para que o resultado de uma consulta seja ordenado pelos valores de um campo especfico, utiliza-se o mtodo order_by().
print item.descricao
...
Doutorado
Graduado
Mestrado
>>>
Figura 33: Ordenao dos registros de uma consulta com o mtodo order_by()
I. filter(): retorna um novo QuerySet com os registros que atendem as condies informadas
nos parmetros do mtodo;
49
II. exclude(): retorna um novo QuerySet com os registros que no atendem as condies
informadas nos parmetros do mtodo.
print item.descricao
...
Graduado
>>> t = Titulacao.objects.exclude(descricao=Graduado)
>>> for item in t:
...
print item.descricao
...
Mestrado
Doutorado
>>>
print item.descricao
...
Mestrado
Doutorado
Figura 35: Utilizao da condio gte na consulta aos registros da tabela Titulacao
50
Resultado
exact
iexact
contains
icontains
gt
gte
lt
lte
in
Valor do campo utilizado na condio seja igual a um dos tens de uma lista
startswith
istartswith
endswith
iendswith
range
year
Para campos do tipo date e datetime, o ano seja igual ao valor informado,
utilizando quatro dgitos
month
day
Para campos do tipo date e datetime, o dia seja igual ao valor informado
isnull
search
Utilizado para busca por contedo apenas no SGBD MySQL, pelo fato de utilizar a indexao do texto disponvel pelo SGBD, desde que este tenha sido
configurado
51
3.7.3
Excluso de Registros
A excluso de registros atravs do framework Django efetuada pelo mtodo delete().
Este mtodo pode ser chamado de um objeto relacionado um registro no banco de dados ou
de um QuerySet. A execuo do mtodo delete() a partir de um QuerySet ir excluir todos os
registros retornados pelo QuerySet.
A excluso de um registro utilizado como chave estrangeira em outros registros far com
que os registros que utilizam esta chave sejam excludos junto com o registro em questo. Este
mecanismo do Django comporta-se da mesma forma que o DELETE CASCADE da linguagem
SQL.
3.8
INTERFACE DE ADMINISTRAO
Algumas aplicaes Web possuem como principal objetivo apresentar determinado contedo aos usurios, como os blogs, os portais de notcias, entre outros. Porm, o contedo
destas aplicaes precisa ser manutenido por algum usurio, atravs de uma interface que
possibilite a manuteno deste contedo. Geralmente, estas interfaces so muito parecidas
em todas as aplicaes Web, e possibilitam ao usurio criar, consultar, alterar e excluir dados
utilizados pela aplicao.
Com o objetivo de facilitar o desenvolvimento destas interfaces de manuteno de contedo, o framework Django oferece uma interface de administrao, criada automaticamente de
acordo com os modelos de dados, possibilitando aos usurios criar, alterar, consultar e excluir
dados das tabelas includas nesta interface.
Para utilizar a interface de administrao do Django, o desenvolvedor deve primeiramente identificar quais modelos de dados sero utilizados na interface de administrao, adicionando a declarao da classe Admin dentro da classe que corresponde ao modelo de dados,
no arquivo models.py, conforme o exemplo a seguir:
52
pontos
def _ _ s t r _ _ ( s e l f ) :
return s e l f . descricao
class Admin :
pass
11
12
matricula
13
nome
14
endereco
15
bairro
16
cidade
17
uf
18
telefone
19
20
salario
21
22
titulacao
23
class Admin :
24
pass
53
INSTALLED_APPS = (
django.contrib.auth ,
django.contrib.contenttypes ,
django.contrib.sessions ,
django.contrib.sites ,
django.contrib.admin ,
piramide.professores
)
Aps realizar estas alteraes, necessrio executar o script manage.py, com a opo
syncdb, para que o Django crie as tabelas utilizadas pela interface de administrao. Neste momento, o Django criar as tabelas necessrias e solicitar a criao de um usurio administrador
para a interface de administrao.
Antes de acessar a interface de administrao, necessrio alterar o arquivo urls.py,
que se encontra no diretrio do projeto. Para ativar o acesso interface de administrao, basta
remover o comentrio da linha referente a interface de administrao, excluindo o caracter #. O
exemplo a seguir mostra como o arquivo urls.py deve ser configurado para ativar a interface de
administrao. Maiores detalhes sobre a configurao de URLs sero vistas no prximo item
deste trabalho.
u r l p a t t e r n s = p a t t e r n s ( ,
# Example :
# Uncomment t h i s f o r admin :
( r ^admin/ , i n c l u d e ( django.contrib.admin.urls ) ) ,
Para verificar se a interface de administrao est funcionando corretamente, basta iniciar o servidor de desenvolvimento do Django, atravs do script manage.py com a opo run-
54
Na pgina inicial da interface de administrao, so apresentadas todas as tabelas selecionadas na definio dos modelos de dados. O Django exibe o nome dos modelos de dados no
plural, porm ele faz isso apenas colocando a letra S no final do nome do modelo. Para corrigir
este nome, necessrio declarar a classe Meta dentro de cada modelo de dados, e informar
um valor para o atributo verbose_name_plural, conforme a figura 40.
pontos
def _ _ s t r _ _ ( s e l f ) :
return s e l f . descricao
class Admin :
pass
10
11
class Meta :
verbose_name_plural = "Titulaes"
Este valor ser reconhecido pelo Django como o nome do modelo de dados no plural.
Com a alterao dos nomes dos modelos de dados, a pgina principal da interface de administrao deve ser semelhante a figura 41.
55
Existem alguns atributos da classe Admin que adicionam recursos na listagem dos registros na interface de administrao. O atributo list_display recebe uma tupla com os campos
que sero exibidos na listagem. O atributo list_filter recebe uma tupla com os campos que
podero ser filtrados atravs de uma seleo na interface de administrao. O atributo search_fields recebe uma tupla com os campos que sero utilizados para localizar um registro na
listagem. A figura a seguir mostra a listagem dos registros na interface de administrao com
esses atributos configurados.
Na insero dos registros, a interface de administrao faz todas as validaes necessrias de acordo com a definio do modelo de dados. Nos campos de chave estrangeira, o
Django oferece um campo para a seleo dos registros da tabela relacionada. Os valores apre-
56
sentados nesta lista so as representaes string dos registros, definidas no mtodo __str__()
do modelo de dados relacionado. A figura 43 mostra as validaes realizadas pela interface de
administrao e o campo Titulacao, com os registros da tabela Titulacao dispostos em uma lista
para seleo.
A interface de administrao oferecida pelo framework Django um dos grandes atrativos da ferramenta. Com ela possvel manutenir os dados da aplicao utilizando uma interface
agradvel e fcil de usar.
3.9
57
import d a t e t i m e
def d a t a h o r a _ a t u a l ( r e q u e s t ) :
datahora = d a t e t i m e . d a t e t i m e . now ( )
h t m l ="""<html> <body>
<p>%s</p>
10
r e t u r n HttpResponse ( h t m l )
58
Significado
. (ponto)
Qualquer caracter
\d
Qualquer nmero
[A-Z]
[a-z]
[A-Za-z]
[^/]+
{1,3}
Para exemplificar a configurao das URLS, ser definido que todas as requisies realizadas na url /agora/ sero respondidas pela view datahota_atual. A figura 45 mostra como criar
este mapeamento. Aps configurar o mapeamento, o acesso ao endereo http://localhost:8000/agora/
deve apresentar a resposta enviada pela view datahora_atual.
u r l p a t t e r n s = p a t t e r n s ( ,
# Example :
# Uncomment t h i s f o r admin :
( r ^admin/ , i n c l u d e ( django.contrib.admin.urls ) ) ,
10
11
( r ^agora/$ , d a t a h o r a _ a t u a l ) ,
)
O acesso ao endereo http://localhost:8000/agora/ deve apresentar uma resposta semelhante a figura 46.
59
Em diversas situaes do desenvolviemento de uma aplicao Web existe a necessidade da passagem de parmetros pela URL para o programa que trata as requisies. Para
atender essa necessidade em uma aplicao desenvolvida com o framework Django, necessrio alterar a configurao das URLs de modo que estas possam receber parmetros e
alterar a definio das views envolvidas, incluindo o parametro necessrio. A figura 47 mostra
a configurao de uma URL que interpreta os parmetros enviados.
( r ^agora/(?P<parametro>\w+)/$ , d a t a h o r a _ a t u a l ) ,
A definio da view deve ser alterada para receber o parmetro. A figura 48 mostra a
definio da view alterada com a incluso de um parmetro, que recebe o valor Nenhum caso
o parmetro no seja passado.
Para situaes em que o desenvolvedor necessita desenvolver uma view para listar os
registros de uma tabela, exibir os detalhes de um registro, agrupar os registros por data ou
simplismente direcionar a URL para um template, o Django oferece uma forma fcil de realizar estas tarefas sem que o desenvolvedor precise escrever uma view para cada situao. As
Views Genricas so implementaes genricas para problemas comuns, como os citados anteriormente. A documentao necessria para o uso das views genricas est disponvel no
endereo (LAWRENCE JOURNAL-WORLD, 2007)
60
3.9.1
AJAX
As requisies AJAX, acrnimo em lngua inglesa para Asynchronous Javascript And
XML, podem ser utilizadas nas aplicaes desenvolvidas com o framework Django. Para tratar
uma requisio AJAX, necessrio definir uma URL e desenvolver uma view, que far todo o
processamento necessrio e enviar a resposta ao solicitante. A figura 49 apresenta uma view
que retorna os dados para o requisitante no formato XML.
def r e q u i s i c a o _ a j a x ( r e q u e s t ) :
<professores>
</professores>
"""
10
r e t u r n HttpResponse ( r e t o r n o , mimetype="text/xml" )
Uma grande necessidade nas aplicaes que utilizam requisies AJAX a tarefa de
transformar o resultado de uma consulta ao banco de dados para o formato XML. O Django
possui uma API que realiza a converso de um QuerySet para o formato XML, chamada de
serializers. Porm, a documentao oficial do projeto alerta os desenvolvedores de que esta
API est sendo completamente alterada e que seria perigoso utiliz-la at que uma nova verso
esteja disponvel.
Uma alternativa ao uso da API serializers a utilizao dos templates, que sero explicados no prximo item deste trabalho.
O framework Django no possui nenhum facilitador para o envio das requisies AJAX
e para o tratamento da resposta enviada pelo servidor. Estas funcionalidades devem ser implementadas pelo desenvolvedor, utilizando a linguagem JavaScript. Existem vrios scripts de
cdigo aberto disponveis na Internet, que auxiliam o desenvolvedor nestas tarefas. O fato de o
framework Django no utilizar nenhum controle no envio das requisies garante ao desenvolvedor a liberdade de escolha dos scripts que melhor atendam as suas necessidades.
61
3.10
TEMPLATES
No item anterior foi apresentada a utilizao das views, onde o cdigo HTML relacionado interface foi escrito diretamente na view, juntamente com o cdigo Python. Esta prtica
no segue o padro MVC, que recomenda separar o cdigo do controller do cdigo relacionado
interface. Esta recomendao justifica-se pelo fato de as empresas de desenvolvimento de
aplicaes Web possurem pessoas diferentes para codificar as regras de negcio e para desenvolver a interface da aplicao. A separao destas funes torna mais fcil a manuteno
da aplicao.
Para atender esta necessidade, o framework Django oferece um sistema de templates
que possibilita ao desenvolvedor escrever um documento de texto com marcaes especficas
da linguagem de template do Django. Esse documento de texto pode ser o cdigo de um
documento HTML, um arquivo XML ou um texto para o envio de e-mails, por exemplo.
Um template pode conter, alm de texto, blocos e variveis da linguagem de template do
Django. Os blocos, delimitados pelas marcaes {% e %}, so utilizados para processamento
condicional, laos de repetio, exibio de valores no documento ou para habilitar o acesso
a outras marcaes de um template. As variveis, delimitadas pelas marcaes {{ e }}, so
utilizadas para exibir valores no documento.
Os valores so passados para as variveis do template atravs de um mapeamento
entre o nome da varivel e o valor que esta ir receber, realizado por um objeto instanciado da
classe Context, o qual chamado de contexto. Os objetos template renderizam um ou mais
contextos para receber os valores das suas variveis.
A figura 50 exemplifica a utilizao de blocos, variveis e contextos em um template,
utilizado o console interativo do projeto. Para utilizar o console interativo do projeto, basta utilizar
o comando python manage.py shell no diretrio do projeto:
62
importante destacar que, para condies em que necessrio comparar dois objetos,
utilizam-se as marcaes {% ifequal objeto1 objeto2 %} e {% ifnotequal objeto1 objeto2 %}, para
igualdade e diferena, respectivamente. Essas marcaes suportam a utilizao da marcao
{% else %} e as marcaes que definem o fim do bloco so {% endifequal %} e {% endifnotequal
%}.
Quando desenvolvidos em arquivos independentes, os templates podem ser armazenados em qualquer diretrio. Porm, este diretrio deve ser informado nas configuraes do
projeto, na opo TEMPLATE_DIRS. Essa opo armazena uma tupla de strings que contm o
diretrio completo onde encontram-se os templates. Quando um programa solicita a utilizao
de um template, o framework Django procura pelo template nos diretrios na ordem em que
estes foram informados na configurao.
TEMPLATE_DIRS = (
/home/django/piramide/templates ,
/home/django/diversos/templates
)
63
<html>
<body>
<ul>
{% f o r i t e m i n t i t u l a c o e s %}
{% e n d f o r %}
< / ul>
< / body>
10
< / html>
def l i s t a _ t i t u l a c a o ( r e q u e s t ) :
r e g i s t r o s = T i t u l a c a o . o b j e c t s . a l l ( ) . order_by ( pontos )
t = g e t _ t e m p l a t e ( titulacao_list.html )
c = Context ( { "titulacoes" : r e g i s t r o s } )
10
html = t . render ( c )
11
r e t u r n HttpResponse ( h t m l )
64
u r l p a t t e r n s = p a t t e r n s ( ,
# Example :
# Uncomment t h i s f o r admin :
( r ^admin/ , i n c l u d e ( django.contrib.admin.urls ) ) ,
10
11
( r ^titulacoes/$ , l i s t a _ t i t u l a c a o ) ,
)
Com todas estas etapas desenvolvidas, necessrio iniciar o servidor de desenvolvimento do Django. O endereo http://localhost:8000/titulacoes/ deve mostrar uma lista com os
registros armazenados no banco de dados, conforme a figura 55.
65
3.11
MANIPULAO DE FORMULRIOS
O framework Django possui uma biblioteca para manipulao de formulrios HTML chamada newforms. A utilizao dessa biblioteca facilita o desenvolvimento de formulrios e a
validao dos dados pelo servidor, de acordo com os tipos de campo utilizados.
Em aplicaes que utilizam a interface de administrao para manipulao dos dados
e apenas exibem o contedo, como site de notcias, pode existir a necessidade da utilizao
de um formulrio. Um exemplo seria um formulrio para contato, onde o usurio informa o seu
nome, o seu e-mail e a mensagem desejada. Porm, em aplicaes que por algum motivo no
utilizam a interface de administrao, existe a necessidade do desenvolvimento dos formulrios
para cadastro, de acordo com os modelos de dados. O Django oferece a possibilidade de criar
um formulrio independente do modelo de dados, como tambm possibilita ao desenvolvedor
criar um formulrio para o cadastro em um modelo de dados especfico.
A criao de um formulrio independente do modelo de dados necessita da definio da
classe do formulrio, com os atributos representando os campos necessrios. Esta definio
pode ser feita em um arquivo independente, definido pelo desenvolvedor. Para exemplificar a
definio de um formulrio, criado um arquivo no diretrio da aplicao professores, chamado
formularios.py. Este formulrio apenas um exemplo, pois no existe a necessidade de existir
um formulrio de contato na aplicao professores. A figura 56 mostra a definio do formulrio
de contato no arquivo formularios.py.
e m a i l = forms . E m a i l F i e l d ( )
mensagem = forms . C h a r F i e l d ( )
66
A figura 57 mostra o cdigo da view professor_add, que inicialmente cria o formulrio de acordo
com o modelo de dados Professor e passa para o template professor_form.html.
def p ro fe ss o r_ ad d ( r e q u e s t ) :
F o r m u l a r i o = forms . form_for_model ( P r o f e s s o r )
t = g e t _ t e m p l a t e ( professores/professor_form.html )
10
i f r e q u e s t . method == POST :
11
dados = r e q u e s t .POST
12
f = F o r m u l a r i o ( dados )
13
if f . is_valid () :
14
c le a n _d a t a = f . c l e a n _ d a t a
15
16
html = t . render ( c )
17
r e t u r n HttpResponse ( h t m l )
18
19
else :
f = Formulario ( )
21
c = Context ( { "formulario" : f } )
22
html = t . render ( c )
23
r e t u r n HttpResponse ( h t m l )
Quando o usurio finaliza o cadastro, os dados so enviados para essa mesma view,
atravs do mtodo POST. Quando a view recebe os dados, faz a validao automtica do
formulrio disponvel no Django. Se os dados inseridos estiverem corretos, a view encaminhaos para o template, com o intuito de apresentar os dados informados pelo usurio. Em uma
aplicao Web, ao invs de retornar os dados para o template, neste momento seria confirmada
a incluso do registro na tabela Professor. Caso a validao encontre erros, os dados so
enviados novamente para o formulrio e os erros so apresentados no template. O cdigo do
template apresentado na figura 58.
67
<html>
<head>
< / head>
<body>
<table>
{ { formulario . as_table } }
10
< / table>
11
<input type="submit">
12
< / form>
13
{% i f dados %}
14
15
{% e n d i f %}
16
< / body>
17
< / html>
3.12
68
De acordo com (HOLOVATY; MOSS, 2006), a utilizao do servidor Web Apache com o
mdulo mod_python atualmente a configurao mais robusta para ambientes de produo
de aplicaes desenvolvidas com o Django. O Apache nas verses 2.x e o mod_python nas
verses 3.x so requisitos para a utilizao desse servidor com o Django.
Para configurar o Django no Apache, necessrio verificar se o mdulo mod_python
est ativo. A ativao do mdulo feita pelo comando LoadModule, no arquivo de configurao
do Apache. Aps verificar o mdulo, necessrio alterar as configuraes do servidor para
reconhecer a aplicao, conforme a figura 60.
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE piramide.settings
PythonPath "[/diretorio_do_projeto] + sys.path"
PythonDebug Off
</Location>
<Location "/media/">
SetHandler None
</Location>
69
Outra forma de disponibilizar estes arquivos para o Apache copiando o diretrio "media" para o diretrio raiz dos documentos do Apache.
Para maiores informaes, o Django Book possui um captulo exclusivo sobre liberao
de aplicaes, disponvel em (HOLOVATY; MOSS, 2006).
O prximo captulo apresenta uma aplicao desenvolvida com o Django para o controle
de alocaes dos professores de uma instituio de ensino.
70
4.1
4.2
REQUISITOS
71
4.3
ITCD =
onde
4.4
MODELAGEM
O modelo entidade-relacionamento do projeto piramide foi desenvolvido a partir das planilhas utilizadas atualmente. A figura 61 mostra o modelo desenvolvido para o projeto.
72
4.5
DESENVOLVIMENTO DA APLICAO
Aps a definio dos requisitos e da modelagem da aplicao, iniciou-se o desenvolvimento com o framework Django. Inicialmente, foram criados o projeto e as aplicaes que
fariam parte do projeto. As aplicaes foram definidas da seguinte forma:
I. Professores: aplicao responsvel pelo cadastro de professores e titulaes. Estes cadastros foram separados em uma aplicao visando a reutilizao em outros projetos.
II. Instituies: aplicao responsvel por manter as informaes da instituio, como o
cadastro de cursos, semestres e atividades. Esta aplicao foi criada visando uma melhor
organizao do projeto.
73
III. Alocaes: aplicao responsvel por manter as informaes de alocao. a principal aplicao do projeto e o seu funcionamento depende das aplicaes Professores e
Instituio.
4.6
RESULTADOS OBTIDOS
74
A figura 63 mostra a tela inicial da aplicao, que possui uma pequena explicao sobre
a funcionalidade disponvel em cada aba da aplicao:
A figura 64 mostra o relatrio de carga horria dos professores, onde o usurio informa
um semestre e um professor para consultar a sua carga horria. O relatrio exibe um detalhamento das alocaes do professor selecionado no semestre e o total de horas, juntamente com
a quantidade de horas especificadas no contrato do professor.
75
4.7
DIFICULDADES ENCONTRADAS
76
CONCLUSO
A demanda pelo desenvolvimento de aplicaes Web est constante crescimento, fazendo com que a procura por profissionais que possuam o conhecimento necessrio para a
construo dessas aplicaes seja grande. Porm, as ferramentas utilizadas atualmente pela
maioria das organizaes para o desenvolvimento de aplicaes Web so complexas e dificultam a busca por profissionais qualificados. Outra desvantagem do uso de tais ferramentas o
tempo gasto no desenvolvimento das aplicaes, que tende a ser elevado.
Como alternativa para as ferramentas atualmente utilizadas no desenvolvimento, este
trabalho apresentou o Django, um framework de desenvolvimento de aplicaes Web que tem
por objetivo facilitar o desenvolvimento das aplicaes, diminuir o tempo utilizado no desenvolvimento e manter a organizao do cdigo das aplicaes desenvolvidas.
A primeira impresso que o desenvolvedor tem com o Django de que tudo muito
fcil, devido a criao automtica da interface de administrao para a manuteno dos dados da aplicao. Porm, no momento da criao das pginas especficas para a exibio do
contedo armazenado, necessrio que o desenvolvedor entenda o fluxo de funcionamento
entre os models, as views e os templates utilizados no desenvolvimento de aplicaes Web
com o framework Django. necessrio tambm que o desenvolvedor possua conhecimentos
no desenvolvimento de pginas HTML e na utilizao da linguagem CSS, pois o Django no
auxilia o desenvolvedor na criao da interface da aplicao, com excesso da interface de
administrao.
A utilizao da linguagem Python facilita a codificao da aplicao, e importante que
o desenvolvedor possua conhecimentos bsicos na linguagem. Os objetos do tipo dicionrio
so muito utilizados, assim como as listas e as tuplas. A configurao das URLs da aplicao
utilizando expresses regulares muito poderosa, porm um pouco complicada para quem no
domina este recurso. Porm, a consulta aos exemplos disponveis na documentao oficial
suficiente para auxiliar o desenvolvedor na configurao das URLs da sua aplicao.
Para verificar se o framework Django era realmente uma boa ferramenta para o desenvolvimento de aplicaes Web, este trabalho apresentou um estudo de caso do desenvolvimento
de uma aplicao para o controle de alocaes dos professores do Instituto Superior Tupy, desenvolvida com o framework Django. Para construir a aplicao, que formada por alguns
cadastros e 4 relatrios, foram gastas aproximadamente 30 horas. Levando em considerao
que o autor estava estudando o Django e no possuia experincia com a linguagem Python,
77
foram utilizadas poucas horas de desenvolvimento. Portanto, possvel concluir que o Django
facilita o desenvolvimento de aplicaes Web e diminui a quantidade de horas gastas com o
desenvolvimento.
Um problema encontrado no Django e que afeta a maioria das solues de cdigo aberto
a quantidade de mudanas realizadas entre uma verso e outra. Essas mudanas contribuem
para a evoluo do framework, porm dificultam a migrao das aplicaes desenvolvidas em
verses anteriores para a verso atual. Durante o desenvolvimento do trabalho, foi necessria
a alterao de alguns exemplos devido a mudana de comportamento de um tipo de campo
oferecido pelo Django. Este tipo de problema deve ocorrer em menor freqncia com o amadurecimento do framework, que muito novo e ainda no chegou na verso 1.0.
Um fator que dificulta a popularizao do framework Django a falta de documentao
em idiomas locais. Toda a documentao est escrita no idioma Ingls e dificulta o aprendizado
dos profissionais que no conheam o idioma. Por esta razo, foram apresentadas neste trabalho as principais funcionalidades do Django, de forma que um desenvolvedor consiga iniciar o
seu aprendizado construindo pequenas aplicaes.
Como sugesto para trabalhos futuros, pode-se estudar as funcionalidades do Django
que no foram apresentadas neste trabalho, como a utilizao do sistema de cache, gerenciamento de sesses, utilizao do Middleware do Django, internacionalizao, views genricas e
apresentar todas as funcionalidades do sistema de templates do Django. Alm disso, pode-se
realizar um estudo comparativo entre o Django e outros frameworks de desenvolvimento de aplicaes Web, estudar a viabilidade da utilizao do Django para o desenvolvimento de solues
Web para gesto empresarial ou estudar a possibilidade de utilizao do framework Django no
ensino superior, em uma disciplina de programao Web.
78
REFERNCIAS
APACHE SOFTWARE FOUNDATION. About the Apache HTTP Server Project. 2007.
Disponvel em: http://httpd.apache.org/ABOUT_APACHE.html.
Acesso em: 04 abr. 2007.
BAREINBOIM, E. Conhea o Apache 2.0. 2006. Disponvel em:
http://olinux.uol.com.br/artigos/405/1.html.
Acesso em: 04 abr. 2007.
BERNERS-LEE, T. Hypertext Style: Cool URIs dont change. 1998. Disponvel em:
http://www.w3.org/Provider/Style/URI.
Acesso em: 10 mai. 2007.
DEITEL, H. et al. Python How To Program. New Jersey: Prentice Hall, 2002. ISBN
0-13-092361-3.
DJANGO SOURCE CODE. DjangoPoweredSites - Django Code. 2007. Disponvel em:
http://code.djangoproject.com/wiki/DjangoPoweredSites.
Acesso em: 09 mai. 2007.
DRAKE, J. D. A Brief Introduction to Apaches mod_python Module. 2005. Disponvel em:
http://www.devx.com/webdev/Article/29357.
Acesso em: 05 abr. 2007.
GALDINO, C. Manual Javascript. 2006. Disponivel em:
http://bardo.castelodotempo.com/javascript.
Acesso em: 06 abr. 2007.
HOLOVATY, A.; MOSS, J. K.
http://www.djangobook.com.
Acesso em: 06 mar. 2007.
LAWRENCE JOURNAL-WORLD.
http://www.djangoproject.com.
Acesso em: 09 mai. 2007.
79
80
professores/models.py
1
pontos
def _ _ s t r _ _ ( s e l f ) :
= models . I n t e g e r F i e l d ( b l a n k = False )
return s e l f . descricao
class Admin :
pass
class Meta :
10
11
12
matricula
13
nome
14
endereco
15
bairro
16
cidade
17
uf
18
telefone
19
= models . E m a i l F i e l d ( b l a n k =True )
20
salario
21
h o r a s _ c o n t r a t o = models . I n t e g e r F i e l d ( b l a n k =False )
22
titulacao
23
def _ _ s t r _ _ ( s e l f ) :
24
25
r e t u r n s e l f . nome
class Admin :
26
l i s t _ d i s p l a y = ( " matricula " , "nome" , " t i t u l a c a o " , " email " , " telefone " )
27
list_filter
81
28
29
30
82
instituicoes/models.py
1
codigo
descricao
def _ _ s t r _ _ ( s e l f ) :
7
8
9
10
11
12
r e t u r n s e l f . codigo
class Meta :
verbose_name_plural = " Cursos "
class Admin :
l i s t _ d i s p l a y = ( codigo , descricao , centro_custo , )
class A t i v i d a d e ( models . Model ) :
13
14
def _ _ s t r _ _ ( s e l f ) :
15
16
17
18
19
20
return s e l f . descricao
class Meta :
verbose_name_plural = " Atividades "
class Admin :
l i s t _ d i s p l a y = ( descricao , )
class Semestre ( models . Model ) :
21
22
def _ _ s t r _ _ ( s e l f ) :
23
24
25
26
27
r e t u r n s e l f . semestre_ano
class Meta :
verbose_name_plural = " Semestres "
class Admin :
l i s t _ d i s p l a y = ( semestre_ano , )
83
alocacoes/models.py
1
from p i r a m i d e . p r o f e s s o r e s . models
import P r o f e s s o r
semestre
professor
curso
atividade
horas_aula
= models . I n t e g e r F i e l d ( b l a n k = False )
10
11
def _ _ s t r _ _ ( s e l f ) :
r e t u r n s e l f . semestre . _ _ s t r _ _ ( ) +
s e l f . professor . __str__ ( )
12
13
14
15
class Meta :
verbose_name_plural = " Alocacoes "
class Admin :
list_display
,)
16
list_filter
17
s e a r c h _ f i e l d s = ( professor , )
84
urls.py
1
urlpatterns = patterns ( ,
( r ^ , i n c l u d e ( piramide . alocacoes . u r l s ) ) ,
admin / l o g i n . html } ) ,
7
9
alocacoes/urls.py
1
( r ^$ , index ) ,
( r ^ carga_horaria / $ , carga_horaria ) ,
relatorio_carga_horaria ) ,
6
( r ^ indice_titulacao /$ , indice_titulacao ) ,
( r ^ professor_curso / $ , professor_curso ) ,
( r ^comparacao_carga / $ , comparacao_carga ) ,
10
relatorio_comparacao_carga ) ,
11
85
Este apndice apresenta o arquivo views.py da aplicao Alocaes, onde est codificada toda a lgica relacionada aos relatrios da aplicao.
alocacoes/views.py
1
@login_required
10
def i n d e x ( r e q u e s t ) :
11
12
h t m l = t . r e n d e r ( Context ( ) )
13
r e t u r n HttpResponse ( h t m l )
15
@login_required
16
def c a r g a _ h o r a r i a ( r e q u e s t ) :
17
18
semestres = Semestre . o b j e c t s . a l l ( )
19
20
21
html = t . render ( c )
22
r e t u r n HttpResponse ( h t m l )
24
@login_required
25
26
27
total_horas = 0
86
28
29
f o r i t e m i n alocacoes :
t o t a l _ h o r a s += i t e m . horas_aula
30
31
32
resultado = t . render ( c )
33
r e t u r n HttpResponse ( r e s u l t a d o )
35
@login_required
36
def i n d i c e _ t i t u l a c a o ( r e q u e s t ) :
37
indice_geral = 0
38
contador_geral = 0
39
indices = [ ]
40
cursos = Curso . o b j e c t s . a l l ( )
41
f o r i t e m i n cursos :
42
43
indice_curso = 0
44
c on ta do r_ cu rs o = 0
45
f o r alocacao i n alocacoes :
46
i n d i c e _ c u r s o += alocacao . p r o f e s s o r . t i t u l a c a o . pontos
47
c on ta do r_ cu rs o += 1 . 0
48
i n d i c e _ g e r a l += i n d i c e _ c u r s o
49
c o n t a d o r _ g e r a l += c o n t a d o r _ c u r s o
50
i f c on ta do r_ cu rs o > 0 :
51
52
indice_curso /= contador_curso
else :
53
indice_curso = 0
54
i n d i c e _ g e r a l = round ( i n d i c e _ g e r a l , 2 )
55
i n d i c e _ c u r s o = round ( i n d i c e _ c u r s o , 2 )
56
57
58
59
60
i f contador_geral > 0:
indice_geral /= contador_geral
else :
indice_geral = 0
61
62
63
html = t . render ( c )
64
r e t u r n HttpResponse ( h t m l )
66
@login_required
67
def p r o f e s s o r _ c u r s o ( r e q u e s t ) :
68
lista_curso = [ ]
69
alocacoes = Alocacao . o b j e c t s . a l l ( )
70
f o r i t e m i n alocacoes :
87
71
l i s t a _ c u r s o . append ( i t e m . curso . i d )
72
cursos = Curso . o b j e c t s . f i l t e r ( i d _ _ i n = l i s t a _ c u r s o )
73
74
75
html = t . render ( c )
76
r e t u r n HttpResponse ( h t m l )
78
@login_required
79
80
81
lista_professor = [ ]
82
f o r i t e m i n alocacoes :
83
l i s t a _ p r o f e s s o r . append ( i t e m . p r o f e s s o r . i d )
84
85
86
87
resultado = t . render ( c )
88
r e t u r n HttpResponse ( r e s u l t a d o )
90
@login_required
91
def comparacao_carga ( r e q u e s t ) :
92
semestres = Semestre . o b j e c t s . a l l ( )
93
94
95
html = t . render ( c )
96
r e t u r n HttpResponse ( h t m l )
98
@login_required
99
100
p r o f e s s o r e s = P r o f e s s o r . o b j e c t s . a l l ( ) . order_by ( "nome" )
101
lista_carga = [ ]
102
103
carga_atual = 0
104
carga_anterior = 0
105
106
107
108
f o r alocacao i n alocacoes :
c a r g a _ a t u a l += alocacao . horas_aula
alocacoes = Alocacao . o b j e c t s . f i l t e r ( semestre__exact = s e m e s t r e _ a n t e r i o r
, professor__exact = professor . id )
109
110
f o r alocacao i n alocacoes :
c a r g a _ a n t e r i o r += alocacao . horas_aula
88
111
112
l i s t a _ c a r g a . append ( v a l o r e s )
114
115
116
resultado = t . render ( c )
117
r e t u r n HttpResponse ( r e s u l t a d o )
89
Este apndice apresenta o arquivo index.html, utilizado como base para o desenvolvimento dos outros templates da aplicao.
templates/alocacoes/index.html
1
< !DOCTYPE HTML PUBLIC " //W3C/ /DTD HTML 4 . 0 1 / /EN" " h t t p : / /www.w3. org /TR/ html4 /
<html>
<head>
<meta h t t p e q u i v = " Contenttype " content= " t e x t / html ; charset=u t f 8" >
< l i n k r e l = " stylesheet " type= " t e x t / css " h r e f = " / site_media / css / s t y l e . css " / >
f u n c t i o n getHTTPRequest ( ) {
v a r h tt p Re q ue s t = n u l l ;
/ / Firefox
10
i f ( window . XMLHttpRequest ) {
11
h tt p Re q ue s t = new XMLHttpRequest ( ) ;
12
13
/ / IE Para implementao f u t u r a
14
e l s e i f ( window . A c t i v e X O b j e c t ) {
15
try {
16
17
18
catch ( e ) {
19
try {
20
21
22
catch ( e ) {
23
h tt p Re q ue s t = f a l s e ;
24
25
26
27
r e t u r n h t t p R e qu e st ;
90
28
29
f u n c t i o n changeItem ( i t e m ) {
30
31
32
33
34
< / script>
35
{% b l o c k s c r i p t %}
36
{% endblock %}
37
38
< / head>
39
<body>
40
41
42
43
44
< l i ><a i d = " tab1 " h r e f = " / carga_horaria / " >Carga H o r r i a < / a>< / l i >
45
46
47
48
< l i ><a i d = " tab5 " h r e f = " / admin / " > A d m i n i s t r a o < / a>< / l i >
49
< l i s t y l e = " f l o a t : r i g h t " ><a i d = " tab6 " h r e f = " / accounts / logout / " >
S a i r < / a>< / l i >
50
51
< / ul>
< / div>
52
< / div>
53
{% b l o c k conteudo %}
54
55
56
<br>
57
58
59
60
91
61
62
63
64
65
< / ul>
66
< / div>
67
{% endblock %}
68
< / body>
69
< / html>
92
Este apndice apresenta o arquivo carga_horaria.html, utilizado para exibio do relatrio de carga horria dos professores por semestre.
templates/alocacoes/carga_horaria.html
1
{% b l o c k s c r i p t %}
function getRelatorio () {
var resultado ;
v a r h tt p Re q ue s t = getHTTPRequest ( ) ;
h tt p Re q ue s t . open ( "GET" , u r l , t r u e ) ;
10
h tt p Re q ue s t . onreadystatechange = f u n c t i o n ( ) {
11
i f ( h t tp R eq u es t . r e a d y S t a t e == 4 ) {
12
i f ( h t tp R eq u es t . s t a t u s == 200) {
13
14
montaRelatorio ( resultado ) ;
15
} else {
16
17
18
h tt p Re q ue s t = n u l l ;
19
20
};
21
h tt p Re q ue s t . send ( n u l l ) ;
22
23
f u n c t i o n m o n t a R e l a t o r i o ( dados ) {
24
var divRelat ;
25
var tabela ;
26
v a r tbody ;
27
var l i n h a ;
93
28
var v a l o r ;
29
v a r h3 ;
30
31
32
33
34
t a b e l a = document . createElement ( t a b l e ) ;
35
37
38
39
40
41
42
t a b e l a . appendChild ( tbody ) ;
43
44
linha
45
c r i a C o l u n a ( l i n h a , dados [ i ] . f i e l d s . semestre ) ;
46
c r i a C o l u n a ( l i n h a , dados [ i ] . f i e l d s . p r o f e s s o r ) ;
47
c r i a C o l u n a ( l i n h a , dados [ i ] . f i e l d s . curso ) ;
48
c r i a C o l u n a ( l i n h a , dados [ i ] . f i e l d s . a t i v i d a d e ) ;
49
c r i a C o l u n a ( l i n h a , dados [ i ] . f i e l d s . horas_aula ) ;
50
tbody . appendChild ( l i n h a ) ;
51
52
t a b e l a . appendChild ( tbody ) ;
53
d i v R e l a t . appendChild ( t a b e l a ) ;
54
55
");
56
h3 . appendChild ( v a l o r ) ;
57
d i v R e l a t . appendChild ( h3 ) ;
58
59
60
h3 . appendChild ( v a l o r ) ;
61
d i v R e l a t . appendChild ( h3 ) ;
62
63
64
var l i n h a
65
66
l i n h a . appendChild ( v a l o r ) ;
67
tbody . appendChild ( l i n h a ) ;
68
94
69
f u n c t i o n c r i a C o l u n a ( l i n h a , conteudo ) {
70
71
72
coluna . appendChild ( v a l o r ) ;
73
l i n h a . appendChild ( coluna ) ;
74
75
</ s c r i p t >
76
{% endblock %}
77
{% b l o c k conteudo %}
78
<script>
79
80
< / script>
81
82
<table>
83
<tr>
84
85
86
<p>Semestre :
87
88
{% f o r semestre i n semestres %}
89
90
{% e n d f o r %}
91
< / select>
92
< / p>
93
<p> P r o f e s s o r :
94
95
{% f o r p r o f e s s o r i n p r o f e s s o r e s %}
96
97
{% e n d f o r %}
98
< / select>
99
< / p>
100
< / div>
101
< / td>
102
103
105
< / div>
106
< / td>
107
</ tr>
108
< / table>
109
< / div>
95
110
111
<script>
javascript : getRelatorio () ;
112
< / script>
113
{% endblock %}