Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 195 lines (113 sloc) 11.777 kb
ddbcea1 @edudobay initial translation
edudobay authored
1 ---
2 layout: default
3 title: tutorial do web.py 0.2
4 ---
5
6 # tutorial do web.py 0.2
7
8 ## Começando
9
10 Então você sabe Python e quer fazer um site. O web.py fornece o código que torna essa uma tarefa fácil.
11
12 Se você quiser fazer o tutorial inteiro, você precisará destes programas: Python, web.py, flup, psycopg2 e Postgres (ou um banco de dados equivalente e adaptador correspondente para Python). Para detalhes, veja [webpy.org](http://webpy.org/).
13
14 Se você já tem um projeto web.py, dê uma olhada na página de [atualização](http://webpy.infogami.com/upgrade_to_point2) (em inglês) para informações sobre migração.
15
16 Vamos começar.
17
18 ## Tratamento de URLs
19
20 A parte mais importante de qualquer site é a estrutura de suas URLs. Suas URLs não são simplesmente aquela coisa que os visitantes vêem e mandam para seus amigos; elas também criam um modelo mental de como seu site funciona. Em sites populares como o [del.icio.us](http://del.icio.us/), as URLs são até uma parte da interface com o usuário. O web.py faz com que criar boas URLs seja fácil.
21
22 Para começar sua aplicação com web.py, abra um novo arquivo de texto (vamos chamá-lo de 'codigo.py') e digite:
23
24 import web
25
26 Isso serve para importar o módulo do web.py.
27
28 Agora precisamos dizer ao web.py qual será nossa estrutura de URLs. Vamos começar com algo simples:
29
30 urls = (
31 '/', 'index' )
32
33 A primeira parte é uma [expressão regular](http://osteele.com/tools/rework/) que corresponde a uma URL, como `/`, `/ajuda/faq`, `/item/(\d+)`, etc. (`\d+` corresponde a uma seqüência de dígitos. Os parênteses pedem que aquela parte da correspondência seja "capturada" para ser usada mais tarde.) A segunda parte é o nome de uma classe para a qual a requisição HTTP deve ser enviada, como `index`, `view`, `welcomes.hello` (este último corresponde à classe `hello` do módulo `welcomes`), ou `get_\1`. `\1` é substituído pela primeira captura feita pela sua expressão regular; as capturas que sobrarem são passadas para a sua função.
34
35 Essa linha diz que queremos que a URL `/` (i.é., a página inicial) seja tratada pela classe chamada `index`.
36
37 Agora precisamos escrever a classe `index`. Apesar de a maioria das pessoas não perceber enquanto navega por aí, seu navegador usa uma linguagem conhecida como HTTP para comunicar-se com a internet. Os detalhes não são importantes, mas o princípio básico é que os visitantes da Web pedem aos servidores web que realizem certas funções (como `GET` ou `POST`) em URLs (como `/` ou `/foo?f=1`).
38
39 `GET` é a função com a qual estamos todos acostumados: é a usada para pedir o texto de uma página da web. Quando você digita `harvard.edu` no seu navegador, ele literalmente pede ao servidor web de Harvard `GET /`. A segunda mais famosa, `POST`, é comumente usada ao enviar certos tipos de formulários, como um pedido para comprar algo. Você usar `POST` sempre que o envio de um pedido _faz alguma coisa_ (como cobrar de seu cartão de crédito e processar um pedido). Isso é crucial, pois URLs do tipo `GET` podem ser transmitidas por aí e indexadas por mecanismos de busca -- você quer isso para a maioria das suas página, mas com certeza _não_ para coisas como processar pedidos (imagine se o Google tentasse comprar tudo no seu site!).
40
41 No nosso código para o web.py, a distinção entre os dois é clara:
42
43 class index:
44 def GET(self):
45 print "Olá, mundo!"
46 Essa função `GET` será chamada pelo web.py sempre que alguém fizer um pedido `GET` para a URL `/`.
47
48 Ok, agora só falta terminar com uma linha que manda o web.py começar a servir as páginas da web:
49
50 if __name__ == "__main__": web.run(urls, globals())
51
52 Isso manda o web.py servir as URLs que listamos acima, procurando as classes no nome de espaços global para o arquivo atual.
53
54 Perceba que, embora eu esteja falando bastante, nós só temos umas cinco linhas de código. É só isso que você precisa para fazer uma aplicação completa com o web.py. Se você for até sua linha de comando e digitar:
55
56 $ python codigo.py
57 Launching server: http://0.0.0.0:8080/
58
59 Você terá sua aplicação web.py executando um servidor web de verdade no seu computador. Visite essa URL e você deverá ver "Olá, mundo!" (Você pode adicionar um endereço IP/porta depois de "codigo.py" para controlar onde o web.py executa o servidor. Você também pode fazê-lo rodar um servidor `fastcgi` ou `scgi`.)
60
61 **Nota:** Você pode especificar o número de porta a usar pela linha de comando desta maneira, se não puder ou não quiser usar o padrão:
62
63 $ python codigo.py 1234
64
65 ## Desenvolvimento
66
67 O web.py também tem algumas ferramentas para nos ajudar com a depuração. Antes do 'if __name__' na última linha, adicione:
68
69 web.webapi.internalerror = web.debugerror
70
71 Isso lhe fornecerá mensagens de erro mais úteis, quando for o caso. Coloque também na última linha `web.reloader`, de modo que ela se torne:
72
73 if __name__ == "__main__": web.run(urls, globals(), web.reloader)
74
75 Isso diz ao web.py que use o "middleware" web.reloader (middleware é uma função intermediária que adiciona certos recursos ao seu servidor web), que recarrega seus arquivos assim que você os edita, de modo que você pode imediatamente ver as alterações no seu navegador. (Contudo, para algumas alterações mais drásticas, você ainda precisará reiniciar o servidor.) Você provavelmente deverá tirar isso ao deixar seu site público, mas é um recurso excelente durante o desenvolvimento. Também há o `web.profiler`, que, no final de cada página, fornece informações sobre quanto tempo cada função tomou, de modo que você possa tornar seu código mais rápido.
76
77 ## Templating
78
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
79 Escrever HTML de dentro do Python pode tornar-se um empecilho; é muito mais divertido escrever código Python de dentro do HTML. Por sorte, o web.py torna isso bastante fácil.
ddbcea1 @edudobay initial translation
edudobay authored
80
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
81 **Nota:** Versões antigas do web.py usavam [Cheetah templates](http://www.cheetahtemplate.org/). Você é, é claro, livre para usar esse ou qualquer outro software com o web.py, mas ele não é mais suportado oficialmente.
ddbcea1 @edudobay initial translation
edudobay authored
82
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
83 Vamos criar um novo diretório para nossos templates (vamos chamá-lo de `templates`). Dentro dele, crie um novo arquivo cujo nome termine em HTML (vamos chamá-lo de `index.html`). Agora, dentro dele, você pode escrever código HTML normal:
ddbcea1 @edudobay initial translation
edudobay authored
84
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
85 <em>Olá</em>, mundo!
ddbcea1 @edudobay initial translation
edudobay authored
86
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
87 Ou você pode usar a linguagem de templates do web.py para adicionar código ao seu HTML:
ddbcea1 @edudobay initial translation
edudobay authored
88
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
89 $def with (nome)
ddbcea1 @edudobay initial translation
edudobay authored
90
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
91 $if nome:
92 Eu só queria dizer <em>olá</em> para $nome.
ddbcea1 @edudobay initial translation
edudobay authored
93 $else:
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
94 <em>Olá</em>, mundo!
ddbcea1 @edudobay initial translation
edudobay authored
95
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
96 **Nota: Atualmente, é necessário usar quatro espaços para a indentação.**
ddbcea1 @edudobay initial translation
edudobay authored
97
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
98 Como você pode ver, os templates parecem-se bastante com arquivos Python, exceto pela instrução `def with` no começo (ela diz com que parâmetros o template é chamado) e os `$`s colocados na frente de qualquer código. Atualmente, o template.py requer que a instrução $def seja a primeira linha do arquivo. Além disso, note que o web.py "escapa" as variáveis que forem usadas -- de modo que se, por alguma razão, o valor da variável `nome` conntém algum código HTML, ela será devidamente "escapada" e aparecerá como texto puro. Se você não deseja esse comportamento, use `$:nome` em vez de `$nome`.
ddbcea1 @edudobay initial translation
edudobay authored
99
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
100 Agora volte ao `codigo.py`. Abaixo da primeira linha, insira:
ddbcea1 @edudobay initial translation
edudobay authored
101
102 render = web.template.render('templates/')
103
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
104 Isso manda o web.py procurar por templates no seu diretório `templates`. Então altere a função `index.GET` para:
ddbcea1 @edudobay initial translation
edudobay authored
105
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
106 nome = 'João'
107 print render.index(nome)
ddbcea1 @edudobay initial translation
edudobay authored
108
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
109 ('index' é o nome do template, e 'nome' é o parâmetro passado para ele)
ddbcea1 @edudobay initial translation
edudobay authored
110
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
111 Visite seu site e ele deverá dizer olá para o João.
ddbcea1 @edudobay initial translation
edudobay authored
112
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
113 **Dica para o desenvolvimento:** Adicione `cache=False` ao final da sua chamada a `render` para que o web.py recarregue seus templates toda vez que você entrar na sua página.
ddbcea1 @edudobay initial translation
edudobay authored
114
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
115 Agora mude sua URL para:
ddbcea1 @edudobay initial translation
edudobay authored
116
117 '/(.*)', 'index'
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
118 e troque a definição de `index.GET` para:
ddbcea1 @edudobay initial translation
edudobay authored
119
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
120 def GET(self, nome):
ddbcea1 @edudobay initial translation
edudobay authored
121
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
122 e apague a linha que define `nome`. Visite `/` e a página deverá dizer olá ao mundo. Visite `/José` e ela deverá dizer olá ao José.
ddbcea1 @edudobay initial translation
edudobay authored
123
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
124 Se você quer aprender mais sobre os templates do web.py, visite a página do [templetor](/templetor) (em inglês).
ddbcea1 @edudobay initial translation
edudobay authored
125
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
126 ## Bancos de dados
ddbcea1 @edudobay initial translation
edudobay authored
127
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
128 Nota: Antes de poder começar a usar um banco de dados, certifique-se de que tem a biblioteca correspondente instalada. Para bancos de dados MySQL, use [MySQLdb](http://sourceforge.net/project/showfiles.php?group_id=22307); para o Postgres, use o [psycopg2](http://initd.org/pub/software/psycopg/).
ddbcea1 @edudobay initial translation
edudobay authored
129
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
130 Acima da sua linha `web.run`, adicione:
ddbcea1 @edudobay initial translation
edudobay authored
131
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
132 web.config.db_parameters = dict(dbn='postgres', user='nome_do_usuario', pw='senha', db='nome_do_banco_de_dados')
ddbcea1 @edudobay initial translation
edudobay authored
133
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
134 (Modifique isto -- especialmente `nome_do_usuario`, `senha`, and `nome_do_banco_de_dados` -- para os valores correspondentes à sua configuração. Usuários do MySQL também devem trocar `dbn` por `mysql`.)
ddbcea1 @edudobay initial translation
edudobay authored
135
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
136 Crie uma tabela simples no seu banco de dados:
ddbcea1 @edudobay initial translation
edudobay authored
137
138 CREATE TABLE todo (
139 id serial primary key,
140 title text,
141 created timestamp default now(),
142 done boolean default 'f' );
143
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
144 E uma linha inicial:
ddbcea1 @edudobay initial translation
edudobay authored
145
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
146 INSERT INTO todo (title) VALUES ('Aprender web.py');
ddbcea1 @edudobay initial translation
edudobay authored
147
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
148 Voltando ao `codigo.py`, modifique a função `index.GET` para:
ddbcea1 @edudobay initial translation
edudobay authored
149
150 def GET(self):
151 todos = web.select('todo')
152 print render.index(todos)
153
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
154 e modifique o tratador de URLs de volta para simplesmente `/`.
ddbcea1 @edudobay initial translation
edudobay authored
155
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
156 Edite o `index.html` de modo que ele se torne:
ddbcea1 @edudobay initial translation
edudobay authored
157
158 $def with (todos)
159 <ul>
160 $for todo in todos:
161 <li id="t$todo.id">$todo.title</li> </ul>
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
162 Visite novamente seu site, e você deverá ver uma tarefa na lista: "Aprender web.py". Parabéns! Você fez uma aplicação completa que lê dados de um banco de dados. Agora vamos também gravar dados no banco de dados.
ddbcea1 @edudobay initial translation
edudobay authored
163
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
164 No final de `index.html`, insira:
ddbcea1 @edudobay initial translation
edudobay authored
165
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
166 <form method="post" action="add"> <p><input type="text" name="title" /> <input type="submit" value="Adicionar" /></p> </form>
167 E modifique sua lista de URLs para que fique assim:
ddbcea1 @edudobay initial translation
edudobay authored
168
169 '/', 'index',
170 '/add', 'add'
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
171 (Você deve ser muito cuidadoso com essas vírgulas. Se você as omitir, o Python juntará as strings e verá `'/index/addadd'` no lugar da sua lista de URLs!)
ddbcea1 @edudobay initial translation
edudobay authored
172
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
173 Agora adicione outra classe:
ddbcea1 @edudobay initial translation
edudobay authored
174
175 class add:
176 def POST(self):
177 i = web.input()
178 n = web.insert('todo', title=i.title)
179 web.seeother('/')
180
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
181 (Viu como estamos usando o método `POST` para isso?)
ddbcea1 @edudobay initial translation
edudobay authored
182
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
183 `web.input` lhe dá acesso às variáveis que o usuário enviou através de um formulário. Para obter dados de elementos com nomes idênticos em formato de lista (por exemplo, uma série de caixas de verificação com o atributo name="nome"), use:
ddbcea1 @edudobay initial translation
edudobay authored
184
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
185 post_data=web.input(nome=[])
ddbcea1 @edudobay initial translation
edudobay authored
186
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
187 `web.insert` insere valores na tabela `todo` do banco de dados e lhe devolve o ID da nova linha. `seeother` redireciona os usuários para esse ID.
ddbcea1 @edudobay initial translation
edudobay authored
188
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
189 Rapidinhas: `web.transact()` inicia uma transação. `web.commit()` confirma a transação e armazena os dados; `web.rollback()` desfaz as alterações. `web.update` funciona como `web.insert`, recebendo (em vez de devolver) um ID (ou uma string com uma sentença `WHERE`) após o nome da tabela.
ddbcea1 @edudobay initial translation
edudobay authored
190
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
191 `web.input`, `web.query` e outras funções do web.py devolvem "Objetos de armazenamento", que são como dicionários mas também permitem que você use `d.foo` além de `d['foo']`. Isso realmente deixa certos códigos mais limpos.
ddbcea1 @edudobay initial translation
edudobay authored
192
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
193 Você pode encontrar todos os detalhes sobre essas e todas as outras funções do web.py na [documentação](http://new.webpy.org/docs) (em inglês).
ddbcea1 @edudobay initial translation
edudobay authored
194
57d8e30 @edudobay tradu\u00e7\u00e3o do texto inteiro
edudobay authored
195 Isso termina o tutorial por enquanto. Dê uma olhada na documentação para ver o monte de coisas legais que você pode fazer com o web.py.
Something went wrong with that request. Please try again.