Desenvolvimento - Python

Criando Formulários no Zope/Plone utilizando o banco de dados MySQL

Este artigo tem como objetivo ensinar como realizar algumas das operações como pesquisa e inclusão de dados em um banco de dados MySQL.

por Fábio Rizzo Matos



Introdução

Uma das tarefas que muitas pessoas tem dúvidas ao trabalharem com o Zope é a criação de formulários que manipulem dados utilizando o Zope/Plone com o ZPT (Zope Pages Templates), Python scripts e Zsql Methods.

Este artigo tem como objetivo ensinar como realizar algumas das operações como pesquisa e inclusão de dados em um banco de dados MySQL.

Os pré-requisitos para a a utilização deste artigo são:

  • Ter o Python e o Zope e o Plone Instalado;
  • Ter instalado o Mysql no Zope;
  • Ter noções de ZPT (Zope Page Templates);
  • Criar o seguinte esquema de tabela no banco de dados:

No meu site www.fabiorizzo.com existe um artigo que ensina a instalar o Python, o Zope e o Plone, Instalando o Mysql no Zope e uma introdução ao ZPT (Zope Page Templates). Uma versão destes artigos podem ser encontrados em meus artigos publicados neste site.

Criando a Conexão com o MySQL

Acesse o ZMI, entre em uma pasta e adicione uma conexão com o banco de dados. No nosso caso o MySQL, veja:

Você irá se deparar com uma janela como essa:

Complete as informações da conexão e clique em add. Depois de criado a conexão, você devera ver o ícone da conexão:

No meu exemplo, eu utilizei uma base de dados de ramais telefônicos. Clique na conexão_teste. Você irá ver algumas opções, onde você deve selecionar Properties.

Clicando em Properties, temos acesso a seguinte janela onde podemos alterar as configurações de nossa conexão:

Clicando na guia Test, podemos executar querys contra no nosso banco de dados para efeitos de teste de conexão. Veja abaixo:

Ao clicar em Submit Query, temos o retorno dos resultados de nossa pesquisa, indicando que o banco esta operando. Clique em Browser para visualizar as tabelas do banco de dados:

Neste meu banco de dados de teste tenho duas tabelas a mais, ramais e transacoes que não fazem parte do nosso artigo. Isso foi feito para ilustrar um ambiente real onde normalmente se tem mais que uma simples tabela. Criando um Formulário de Pesquisa

Vamos criar agora um formulário de pesquisa a base de dados criada, utilizando ZPT (Zope Pages Templates) e o engine do Plone.

Acesse o ZMI e clique em Page Templates:

Ao clicar em add, teremos uma tela onde temos informações sobre o novo arquivo:

O campo File contém um espaço onde podemos importar um arquivo simples em HTML ou XML para servir como base para criarmos os nossos ZPT´s. Clique em Add and Edit.

Você vai ver o seguinte conteúdo:

Vamos alterar o texto do Page Template para o seguinte:

<html>
  <head>
    <title tal:content="template/title">The title</title>
  </head>
  <body>
    <FORM action="." method=get>
    <P>Digite o Nome da Pessoa que você quer saber o ramal.</P>
    <TABLE>  <TBODY>
    <TR>
    <TH>Nome</TH>
    <TD><INPUT name=Usuario width="30"></TD>
    </TR>
    <TR>
    <TH></TH>
    <TD><INPUT type=submit value="Pesquisar Ramal" name=template:method></TD>
    </TR>
    </TBODY></TABLE></FORM>
  </body>
</html>

Salve o Template e clique em Test. Assim poderá visualizar o que você fez. Veja a saída desse código:

Como visto, este código não contém muita nada de especial, somente html e uma parte do ZPT, que é a seguinte:

<title tal:content="template/title">The title</title>

E essa parte faz o trabalho de pegar na propriedade do template o title e exibir o seu valor no lugar onde está o The title.

Porém como visto acima, a página não está dentro do layout do Plone (skin). Para que a page template fique dentro do skin basta modificar algumas linhas no código (as mudanças estão em negrito destacado):

<html metal:use-macro="here/main_template/macros/master">
  <head>
    <title tal:content="template/title">The title</title>
  </head>
  <body><div metal:fill-slot="main">
    <FORM action="." method=get>
    <P>Digite o Nome da Pessoa que você quer saber o ramal.</P>
    <TABLE>  <TBODY>
    <TR>
    <TH>Nome</TH>
    <TD><INPUT name=Usuario width="30"></TD>
    </TR>
    <TR>
    <TH></TH>
    <TD><INPUT type=submit value="Pesquisar Ramal" name=template:method></TD>
    </TR>
    </TBODY></TABLE></FORM>
  </div></body>
</html>
Salve o arquivo e clique em Test e veja o resultado:

Pronto, agora estamos dentro do Layout do Plone.

Agora vamos criar uma Z SQL Method para a busca das informações. Veja:

Clique em Add e vamos configurar:

Clique em ADD. Agora temos um formulário para consultar e criamos uma query do sql. Agora vamos criar um formulário para visualizar os dados de nossa consulta. Agora adicione um Z Search Interface:

Ao clicar teremos uma janela com as configurações do Objeto:

Iremos selecionar a nossa Z SQL Method que criamos, a zsql_select, colocaremos o nome page template de template, pois esse foi o nome que definimos no form de pesquisa. O campo Search Input Id deverá ser o mesmo do seu Campo no formulário de pesquisa e o de seu campo Arguments do seu zsql_select. Ao clicar em ADD você terá alguns:

Como você pode perceber, temos o template que criamos e um outro objeto, o Usuario. Ao abrir o arquivo podemos ver que ele se trata de um form de pesquisa, semelhante ao formulario_pesquisa que criamos anteriormente. Veja:

Porém, este é um formulário que não está "lapidado" conforme nossas necessidades. Podemos então ignora-lo ou simplesmente deletá-lo.

Agora precisamos customizar o template, para que ele mostre os resultados usando o skin do plone.
Veja o código:

<html metal:use-macro="here/main_template/macros/master">

  <body><div metal:fill-slot="main" tal:define="results  here/zsql_select;
                    start request/start|python:0;
                    batch python:modules["ZTUtils"].Batch(results, 
                                                          size=20, 
                                                          start=start);
                    previous python:batch.previous;
                    next python:batch.next">

  <p>
    <a tal:condition="previous"
       tal:attributes="href string:${request/URL0}?start:int=${previous/first}"
       href="previous_url">previous <span tal:replace="previous/length">20</span> 
results</a>
    <a tal:condition="next"
       tal:attributes="href string:${request/URL0}?start:int=${next/first}"
       href="next_url">next <span tal:replace="next/length">20</span> results</a>
  </p>

  <table border>
        <tr>
          <th>Cod</th>
          <th>Usuario</th>
          <th>Unidade</th>
          <th>Ramal</th>
          <th>Radio</th>
          <th>Celular</th>
          <th>Email</th>
        </tr>
       
  <div tal:repeat="result batch" >
  
         <tr>
          <td><span tal:replace="result/cod">cod goes here</span></td>
          <td><span tal:replace="result/usuario">usuario goes here</span></td>
          <td><span tal:replace="result/unidade">unidade goes here</span></td>
          <td><span tal:replace="result/ramal">ramal goes here</span></td>
          <td><span tal:replace="result/radio">radio goes here</span></td>
          <td><span tal:replace="result/celular">celular goes here</span></td>
          <td><span tal:replace="result/email">email goes here</span></td>
        </tr>

  </div>

      </table>
  <p>
    <a tal:condition="previous"
       tal:attributes="href string:${request/URL0}?start:int=${previous/first}"
       href="previous_url">previous <span tal:replace="previous/length">20</span> 
results</a>
    <a tal:condition="next"
       tal:attributes="href string:${request/URL0}?start:int=${next/first}"
       href="next_url">next <span tal:replace="next/length">20</span> results</a>
  </p>

  </div></body>
</html>

Neste código, nós implementamos a Skin do Plone, e as nossas querys vão aparecer dentro do Plone. Com este arquivo, finalizamos a criação de um formulário de pesquisa de dados.

Criando um Formulário de Inclusão

Vamos criar um formulário que inclua dados dentro de um banco de dados. Para tal, adicone um novo page template.

Acesse o ZMI e clique em Page Templates:

E coloque os dados:

Vamos adicionar o seguinte código nele:

<html metal:use-macro="here/main_template/macros/master">
  <head>
    <title tal:content="template/title">The title</title>
  </head>
  <body> <div metal:fill-slot="main">
    
<FORM action="." method=post>
<h1>Coloque as informações do Usuário a ser cadastrado</h1><br>
<TABLE>
<TBODY>
<TR>
<TH>Nome</TH>
<TD><INPUT name=Usuario width="50" value=""></TD>
</TR>
<TR>
<TH>Unidade</TH>
<TD><INPUT name=Unidade width="50" value=""></TD>
</TR>
<TR>
<TH>Ramal</TH>
<TD><INPUT name=Ramal width="30" value=""></TD>
</TR>
<TR>
<TH>Radio</TH>
<TD><INPUT name=Radio width="30" value=""></TD>
</TR>
<TR>
<TH>Celular</TH>
<TD><INPUT name=Celular width="30" value=""></TD>
</TR>
<TR>
<TH>Email</TH>
<TD><INPUT name=Email width="50" value=""></TD>
</TR>
<TR>
<TH></TH>
<TD><INPUT type=submit value="inserir" name="py_inclui:method"></TD>
</TR>
</TBODY>
</TABLE>
</FORM>

  
  </div></body>
</html>
Depois de Salvar, clique em Test e visualize page template.

Depois de criado o formulário, é necessário que nós criarmos um Z SQL Method para incluir os dados na base.

Acesse o ZMI e Crie um Z SQL Method:

Com os dados:

Clique em Add.

Agora que criamos a query SQL, vamos criar o script python, que será o responsável pela inclusão dos dados no banco.

Acesse o ZMI e adicone um Script (Python):

Coloque o nome de py_inclui:

Clique em Add and Edit.

Você terá acesso a um novo script:

Vamos modificar esse conteudo por outro. Veja:

# Pega as variáveis do Ambiente
################################################
request = container.REQUEST
RESPONSE =  request.RESPONSE

################################################
# Recebe os valores da Pagina
################################################
usuario = request.get("Usuario")
unidade = request.get("Unidade")
ramal = request.get("Ramal")
radio = request.get("Radio")
celular = request.get("Celular")
email = request.get("Email")

################################################
# Insere as informações no banco
################################################
context.zsql_insert(Usuario=usuario,Unidade=unidade,Ramal=ramal,
Radio=radio,Celular=celular,Email=email)

return "Ok"

A lista do parameters é: Usuario,Unidade,Ramal,Radio,Celular,Email

Para testar o script, clique em test:

Coloque os valores nas variáveis e clique em Run Script. Se não retornar nenhum erro e a tela mostrar ok, o script esta funcionando. Então vamos testar o nosso formulário. Acesse o formulario_inclusao e clique em test:

Digite as informações e clique em inserir:

Você deverá ver uma mensagem como esta acima, informando que a inclusão foi feita com sucesso. Use o formulario_pesquisa e veja os dados que você incluiu estão disponíveis.
Porém, o nosso ok esta totalmente fora do skin do Plone.

Vamos criar uma página para mostrar que a inclusão foi feita com sucesso. Adicione um novo page template:

Com os seguintes dados:

Clique em Add and Edit. Coloque o seguinte código:

<html metal:use-macro="here/main_template/macros/master">

  <head>
    <title tal:content="template/title">The title</title>
  </head>
  <body>
  <div metal:fill-slot="main">

<h3><span tal:replace="options/mensagem | default"></span></h3>

   </div>

  </body>
</html>

Vamos analizar esse código. O que temos de novidade aqui é o seguinte código:

<h3><span tal:replace="options/mensagem | default"></span></h3>

Definimos esta área para que o nosso script, possa retornar um valor para ele. Vamos modificar o script py_insere:

# Pega as variáveis do Ambiente
################################################
request = container.REQUEST
RESPONSE =  request.RESPONSE

################################################
# Recebe os valores da Pagina
################################################
usuario = request.get("Usuario")
unidade = request.get("Unidade")
ramal = request.get("Ramal")
radio = request.get("Radio")
celular = request.get("Celular")
email = request.get("Email")

################################################
# Insere as informações no banco
################################################
context.zsql_insert(Usuario=usuario,Unidade=unidade,Ramal=ramal,
Radio=radio,Celular=celular,Email=email)

#################################################
# Retorna para o template as informações
#################################################
mensagem = "Usuário Cadastrado com sucesso!"
return context.resposta(mensagem=mensagem)

Como podemos visualizar, a parte que está em negrito é a parte modificada do código. O código return context.resposta(mensagem=mensagem) diz ao zope para retornar a página responsta e no campo mensagem colocar o valor da variavel mensagem. Ao testarmos novamente o nosso formulario_inclusao não teremos mais o ok e sim a seguinte tela:

Conclusão

Com este artigo podemos ver o quanto é simples o uso de banco de dados com o Zope/Plone. Esse tipo de formulário não está levando em conta a validação de dados e muito menos o uso de tecnologias como o Formulator que é utilizado para a criação de formulários.

Em Breve estarei escrevendo outros artigo sobre o tema. Espero ter ajudado. Quem tiver dúvidas, entrem em contato comigo no meu site em: www.fabiorizzo.com ou em meu fórum em: www.fabiorizzo.com/forum.

Até o próximo,

Fabio Rizzo Matos
fabio@fabiorizzo.com
www.fabiorizzo.com

Fábio Rizzo Matos

Fábio Rizzo Matos - Membro ativo da Comunidade Python/Zope e Plone, para qual escreve diversos artigos. Arquiteto de Software e Desenvolvedor, trabalha atualmente na ThreePointsWeb (contato@threepointsweb.com), empresa especializada em desenvolvimento e treinamentos Python, Zope e Plone, realizando treinamentos e consultorias em Plone. Mantenedor do site http://www.fabiorizzo.com além de responsável pela tradução de conteúdo.