Passo-a-Passo web2py, 4º Passo

No 3º passo acompanhamos como é possível inserir registros no banco de dados e como validar a inserção desses registros, para que não aconteça nenhuma inserção errônea ou indesejada.

Além disso, conhecemos o appadmin. O appadmin nada mais é do que um controle que o web2py traz para tudo que iremos fazer hoje: ele permite realizar operações CRUD no nosso banco de dados. Vamos ver como isso funciona!

Segue o índice para que você acompanhe também os outros passos:

O que é CRUD?

Afinal, estou falando desde o último passo sobre essas tais operações, mas ainda não paramos para entender o que elas são de fato. Pois bem, CRUD é um termo do inglês que indica Create, Read, Update e Delete, ou em português: Criar, Ler, Atualizar e Apagar. Cada uma dessas ações reflete uma operação que realizamos no banco de dados.

  • Create: O objetivo da operação create é adicionar informações ao banco de dados. É exatamente o que fizemos no passo anterior: gravamos dados de filmes no banco de dados.
  • Read: A operação read é aquela que solicita informações ao banco de dados. Ou seja, é quando pedimos ao banco de dados para nos mostrar algo que está salvo dentro dele.
  • Update: Quando pedimos para fazer o update de algo, significa que estamos pedindo para atualizar ou mudar aquilo. Da mesma forma, a operação update é aquela que demanda a alteração de alguma informação contida no banco de dados.
  • Delete: A operação delete é exatamente o que você deve estar imaginando. Com ela apagamos alguns registros do banco de dados.

Dentre essas quatro operações, já experimentamos a primeira no passo anterior. Vimos como é possível nos conectar ao banco de dados e inserir informações para que estas fiquem salvas. Portanto, vamos prosseguir descobrindo as outras três.

Read

A partir do último passo, fomos capazes de inserir filmes no nosso banco de dados, mas ainda não conseguimos visualizar os filmes inseridos. Ou seja, eu tenho filmes salvos, mas eu não consigo ver quais filmes são esses. Por isso, agora precisamos de uma página para exibi-los.Vamos criar uma nova página com o seguinte código no controller default.py:

def ver_filmes():
    filmes = db(Filmes).select()
    return dict(filmes=filmes)

Acesse a página http://localhost:8000/locadora/default/ver_filmes

Página ver_filmes()

Página ver_filmes()

Veja que agora temos a listagem de todos os filmes que existem no banco de dados. Então vamos entender como isso funciona:

filmes = db(Filmes).select()

A sintaxe db(query) é utilizada para pesquisar informações no banco de dados. Nós chamamos de query uma expressão que formamos para indicar que tipo de informações nós queremos receber do banco de dados.

Pense no seguinte: eu tenho um pacote de balas coloridas, sendo que cada cor é um sabor. Eu sei que as balas verdes são de limão e eu não gosto de limão, então não quero balas verdes. Por isso, se eu for pedir para alguém pegar uma bala para mim, vou pedir da seguinte forma: “Me dê uma bala por favor, exceto as verdes”.

Esse tipo de expressão pode ser considerada uma query: estou pedindo para fazer uma seleção de registros que não incluam um determinado tipo. No caso dos filmes, eu poderia utilizar algumas querys como essas:

  • Filmes.lancamento >= 2000: para buscar por filmes que possuem um ano de lançamento maior ou igual ao ano 2000.
  • Filmes.generos.contains(‘Animação’): para buscar por filmes que tenham um gênero de animação.
  • (Filmes.lancamento >= 2000) & (Filmes.generos.contains(‘Animação’)): para buscar por filmes que possuem um ano de lançamento maior ou igual ao ano 2000 e ao mesmo tempo tenham um gênero de animação.

Perceba a forma como estruturamos nossa pesquisa no banco de dados:

tabela_do_bd.campo comparação

Ou seja, as querys realiza uma comparação para verificar quais registros são compatíveis ao que você deseja, e então mostra os registros para você.

Além disso, o sinal & e o sinal | significam, respectivamente, and e or. Assim, quando utilizamos esses operadores na nossa query estamos fazendo uma intersecção ou uma união do que desejamos receber do banco de dados.

Relembrando o que nós fizemos:

filmes = db(Filmes).select()

Nossa query é composta apenas pela nossa variável Filmes. Fizemos isso pois queremos selecionar todos os registros da tabela filmes, sem exceções.Depois de informar ao nosso db a query do que desejamos, utilizamos o método select(). A função deste método é selecionar no nosso banco de dados todos os registros compatíveis com a nossa query e retornar esses registros. Por isso, gravamos o nosso select na variável filmes (com letra minúscula). Agora, todos os filmes que nosso select encontrou estão gravados nessa variável na forma de rows. Rows são um tipo próprio da DAL do web2py, que indica registros selecionados. Para trabalharmos com as rows, basta vermos elas como listas. Ou seja, são listas de registros do banco de dados.

Update

Agora que somos capazes de ver nossos registros, conseguimos ver o que temos de errado também. Por exemplo, na minha lista de filmes, eu esqueci de adicionar uma imagem de capa para todos eles. Por isso, agora eu preciso editar esses registros para conseguir fazer o upload dessa imagem.Adicione o seguinte código ao controller:

def editar_filme():
    form = SQLFORM(Filmes, request.args(0, cast=int))
    if form.process().accepted:
        session.flash = 'Filme atualizado: %s' % form.vars.titulo
        redirect(URL('ver_filmes'))
    elif form.errors:
        response.flash = 'Erros no formulário!'
    else:
        if not response.flash:
            response.flash = 'Preencha o formulário!'
    return dict(form=form)

A maior parte dos elementos desta página nós já conhecemos, pois ela é bastante parecida com a página novo_filme. Porém, há um detalhe que faz a diferença neste caso:

SQLFORM(Filmes, request.args(0, cast=int))

A diferença aqui é este segundo elemento dentro do SQLFORM. O segundo elemento é o id, ou seja, o identificador de um registro. Assim, o SQLFORM entende que, quando não passarmos um valor de id para ele, ele deve gerar um formulário para inserir novos registros. Mas caso passemos algum valor de id, ele deve gerar um formulário para editar um registro existente, e esse registro deve ser aquele que tiver o id indicado na tabela indicada.E que valor é esse que estamos passando? Bom, vamos lembrar o que vimos no passo anterior. Uma URL tem o seguinte formato: http://dominio.com/application/controller/function/arg1/arg2?var1=2&var2=3Neste caso, temos que argumentos são aqueles separados por / depois do nome da página e variáveis são aquelas separadas por ? e &. Assim, quando queremos pegar o valor de um argumento ou de uma variável que estão na URL, devemos usar funções específicas.request.args(index) é uma função que captura o valor dos argumentos. Os argumentos de uma URL são guardados no formato de uma lista, por isso, para recebermos o valor de um argumento específico, devemos passar o índice desse argumento na lista. Por exemplo: request.args(0) vai pegar o primeiro elemento da lista.Além disso, o request.args() tem um parâmetro opcional chamado cast para especificar o tipo de retorno que você deseja ter. Por padrão, todos os argumentos estão em formato de string, mas caso você queira receber um determinado argumento no formato inteiro, por exemplo, configuraria o cast como int.Não iremos capturar nenhuma variável agora, mas para fins de conhecimento, as variáveis também podem ser vistas a partir do request.vars. A diferença é que elas são transformadas em um formato de dicionário, ao contrário do request.args que é uma lista. Assim, uma variável chamada var1 pode ter seu valor recuperado fazendo request.vars.var1.Acesse a página de edição com um id existente no seu banco de dados.

Página editar_filme()

Página editar_filme()

Repare que agora temos as informações do nosso filme para que possamos editá-lo. Além disso, o formulário exibe o id do registro. Caso não queira o id aparecendo, adicione mais um parâmetro ao SQLFORM da forma showid=False.

Irei adicionar uma capa ao primeiro filme da minha lista.

Upload de arquivo

Upload de arquivo

Repare que o web2py indica o arquivo salvo.

Quando fazemos um upload de arquivo o web2py armazena esses arquivos em uma pasta própria chamada uploads. Essa pasta fica dentro da pasta da sua aplicação, no mesmo nível dos models e controllers. Cada arquivo que é feito o upload recebe uma hash como nome.

Pasta de uploads

Pasta de uploads

No futuro, iremos entender melhor como funciona a exibição destes arquivos. No momento apenas é importante entender como ficam armazenados.

Delete

Meu DVD do filme Toy Story estragou e eu não penso em repô-lo tão cedo, por isso acho melhor apenas tirá-lo da lista. Por sorte, é muito fácil fazer isso com o web2py.

Vamos criar uma página apenas para deletar filmes:

def apagar_filme():
    db(Filmes.id==request.args(0, cast=int)).delete()
    session.flash = 'Filme apagado!'
    redirect(URL('ver_filmes'))

Aqui vemos que a ideia é a mesma do select, estamos separando os registros a partir de uma query. No caso, estamos separando os registros que tenham o id igual ao que eu receberei pelo request.args(0). Como os ids são únicos por tabela, não corro o risco de apagar mais de um filme.

Depois de separar o registro que desejamos, chamamos o método delete(), é ele que tem a função de sumir com esse registro da nossa tabela.

Simples assim, temos nosso registro apagado. Por último apenas exibimos uma mensagem ao usuário e redirecionamos de volta à página de visualização dos filmes. Note que não temos um return dict(), pois não precisamos exibir uma página ao usuário, apenas realizar a ação de deleção e voltar para uma página que realmente tenha conteúdo.

Conclusão

Conseguimos realizar todas as operações de CRUD utilizando o web2py! Além disso, ainda conseguimos entender como funciona o request.args, o request.vars e o upload de arquivos. Fizemos tudo isso para a tabela de filmes, agora é seu dever fazer para as outras.

Lembrando que o código completo pode ser acessado em: https://github.com/juliarizza/locadora e cada novo passo é um branch no repositório.

Espero você no próximo passo!

Anúncios

12 comentários sobre “Passo-a-Passo web2py, 4º Passo

  1. carduglo disse:

    Muito bom! Até aqui consegui fazer funcionar as funções ver_filmes, editar_filmes e deletar_filmes. E tudo isso sem ainda ter aberto seu endereço do github (que são minhas muletas, mas só abro depois que faço virar os exercícios aqui no browser), pois não quero me influenciar com seu código que na minha opinião é perfeito. É claro que tenho enfrentado alguns problemas de paginas não funcionarem logo de prima…Mas creio que faz parte da programação e como tenho tentado fzr algumas coisas diferentes das suas, tenho esbarrado nessas dificuldades, mas tem sido bom pra aprender a depurar eventuais erros. Voce me apresentou um excelente desafio, estou muito incentivado com seu tutorial e muito inclinado em me inscrever no seu próximo curso (Verificando minhas finanças…). Só tenho que te agradecer por ter-me dado a oportunidade de conhecer mais essa possibilidade. Que Deus a abençoe!

    Curtir

    • Júlia Rizza disse:

      Pode ficar tranquilo que isso é mais que o normal! Nem sempre minhas páginas funcionam de primeira também, mas isso o GitHub não mostra e a gente mantém em segredo, viu? haha Fico muito feliz de saber que está conseguindo se desenvolver com o framework e até arriscando fazer coisas além do que estou mostrando aqui. Espero muito te ver nas próximas turmas do curso!
      Parabéns e continue assim, porque o resultado deve ficar incrível 😀

      Curtido por 2 pessoas

  2. Joilson disse:

    Julia,
    Supondo que eu tenha uma coluna MyDelete e ao invés de deletar o registro, queira gravar nessa coluna o valor “” (vazio) e dizer a aplicação que retorne a consulta onde MyDelete = “” (vazio), como ficaria?

    Curtir

  3. DANIEL PEREIRA PEDROSA DOS SANTOS disse:

    Olá Júlia, estou começando à aprender Python e Web2py. Gostei muito do passo a passo, mais infelizmente, no Update deu erro 404 NOT FOUND. Percebi que quando tiro essa parte do código request.args(0, cast=int), o formulária aparece.

    Curtido por 1 pessoa

  4. Douglas Neves disse:

    O mesmo erro ocorreu comigo, ao acessar a página “editar_filme” retorna erro 404 NOT FOUND. Nem o “apagar_filme” funciona, somente as páginas de “novo_filme” e “ver_filmes”. Consegue me ajudar? Será que é versão do web2py?

    Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

w

Conectando a %s