Web2py - Formulários e validadores

web2py vem com funções poderosas para geração de formulários. Quatro maneiras distintas de construir formulários em web2py são as seguintes -

  • FORM- Em termos de helpers HTML, é considerada uma implementação de baixo nível. Um objeto FORM está ciente do conteúdo de seu campo.

  • SQLFORM - Fornece as funcionalidades de Criar, Atualizar e Excluir ao banco de dados existente.

  • SQLFORM.factory- É considerada uma camada de abstração no topo do SQLFORM, que gera um formulário semelhante ao SQLFORM. Aqui, não há necessidade de criar um novo banco de dados.

  • CRUD Methods - Como o nome sugere, fornece recursos de Criar, Recuperar, Atualizar e Excluir com funcionalidades semelhantes baseadas em SQLFORM.

FORMATO

Considere um aplicativo que aceita uma entrada do usuário e tem um botão “enviar” para enviar a resposta.

Controlador

O controlador “default.py” incluirá a seguinte função associada

def display_form():
   return dict()

Visão

A visualização associada "default / display_form.html" renderizará a exibição do formulário em HTML como -

{{extend 'layout.html'}}
<h2>Basic Form</h2>

<form enctype = "multipart/form-data" action = "{{= URL()}}" method = "post">
   Your name:
   <input name = "name" />
   <input type = "submit" />
</form>

<h2>Submitted variables</h2>
{{= BEAUTIFY(request.vars)}}

O exemplo acima é o formulário HTML normal, que pede a entrada do usuário. O mesmo formulário pode ser gerado com os auxiliares como o objeto FORM.

Controlador

def display_form():
   form = FORM('Value:', INPUT(_value = 'name'), INPUT(_type = 'submit'))
   return dict(form = form)

A função acima no controlador “default.py” inclui o objeto FORM (helper HTML) que ajuda na criação do formulário.

Visão

{{extend 'layout.html'}}
<h2>Basic form</h2>

{{= form}}
<h2>Submitted variables</h2>

{{= BEAUTIFY(request.vars)}}

Ele forma que é gerada pela declaração {{= form}}serializa o objeto FORM. Quando um usuário preenche o formulário e clica no botão enviar, o formulário se auto-submete e a variávelrequest.vars.value junto com seu valor de entrada é exibido na parte inferior.

SQLFORM

Ajuda na criação de um formulário para o banco de dados existente. As etapas para sua implementação são discutidas a seguir.

Estabelecendo conexão com o banco de dados usando DAL, este é criado usando o objeto DAL, que também é chamado de construtor DAL. Depois de estabelecer a conexão, o usuário pode criar a respectiva tabela.

db = DAL('sqlite://storage.sqlite')
db.define_table('employee', Field('name', requires = IS_NOT_EMPTY()))

Assim, criamos uma tabela chamada “funcionário”. O controlador constrói o formulário e o botão com as seguintes instruções -

form = SQLFORM(
   db.mytable,
   record = mytable_index,
   deletable = True,
   submit_button = T('Update')
)

Portanto, para a tabela de funcionários criada, a modificação no controlador seria -

def display_form():
   form = SQLFORM(db.person)

Não há modificação em View. No novo controlador, é necessário construir um FORM, já que o construtor SQLFORM construído a partir da tabela db.employee é definido no modelo. O novo formulário, quando serializado, aparece da seguinte maneira -

<form enctype = "multipart/form-data" action = "" method = "post">
   
   <table>
      <tr id = "employee_name__row">
         <td>
            <label id = "person_name__label" for = "person_name">Your name: </label>
         </td>
         
         <td>
            <input type = "text" class = "string" name = "name" value = "" id = "employee_name" />
         </td>
         
         <td></td>
      </tr>

      <tr id = "submit_record__row">
         <td></td>
         <td><input value = "Submit" type = "submit" /></td>
         <td></td>
      </tr>
		
   </table>

   <input value = "9038845529" type = "hidden" name = "_formkey" />
   <input value = "employee" type = "hidden" name = "_formname" />
	
</form>

Todas as tags no formulário têm nomes derivados da tabela e do nome do campo.

A SQLFORMO objeto também lida com campos de "upload" salvando os arquivos carregados na pasta "uploads". Isso é feito automaticamente. SQLFORM exibe valores “booleanos” na forma de caixas de seleção e valores de texto com a ajuda de“textareas”.

O SQLFORM também usa o método de processo. Isso é necessário se o usuário deseja manter os valores com um SQLFORM associado.

E se form.process(keepvalues = True) então é aceito.

Exemplo

def display_form():
   form = SQLFORM(db.employee)
if form.process().accepted:
   response.flash = 'form accepted'

elif form.errors:
   response.flash = 'form has errors'
else:
   response.flash = 'please fill out the form'

return dict(form = form)

SQLFORM.factory

Às vezes, o usuário precisa gerar um formulário de forma que haja uma tabela de banco de dados existente sem a implementação do banco de dados. O usuário simplesmente deseja aproveitar a vantagem do recurso SQLFORM.

Isso é feito via form.factory e é mantido em uma sessão.

def form_from_factory():
   form = SQLFORM.factory(
      Field('your_name', requires = IS_NOT_EMPTY()),
      Field('your_image', 'upload'))

   if form.process().accepted:
      response.flash = 'form accepted'
      session.your_name = form.vars.your_name
      session.your_image = form.vars.your_image
   elif form.errors:
      response.flash = 'form has errors'

   return dict(form = form)

O formulário aparecerá como SQLFORM com nome e imagem como seus campos, mas não existe tal tabela no banco de dados.

A visualização "default / form_from_factory.html" representará como -

{{extend 'layout.html'}}
{{= form}}

Métodos CRUD

CRUDé uma API usada em cima do SQLFORM. Como o nome sugere, ele é usado para criação, recuperação, atualização e exclusão de forma apropriada.

CRUD, em comparação com outras APIs em web2py, não é exposto; portanto, é necessário que seja importado.

from gluon.tools import Crud
crud = Crud(db)

O objeto CRUD definido acima fornece a seguinte API -

Sr. Não API e funcionalidade
1

crud.tables()

Retorna uma lista de tabelas definidas no banco de dados.

2

crud.create(db.tablename)

Retorna um formulário de criação para o table tablename.

3

crud.read(db.tablename, id)

Retorna um formulário somente leitura para tablename e id de registro.

4

crud.delete(db.tablename, id)

apaga o registro

5

crud.select(db.tablename, query)

Retorna uma lista de registros selecionados da tabela.

6

crud.search(db.tablename)

Retorna uma tupla (formulário, registros), onde formulário é um formulário de pesquisa.

7

crud()

Retorna um dos itens acima com base no request.args ().

Criação de Formulário

Vamos criar um formulário. Siga os códigos fornecidos abaixo.

Modelo

Um novo modelo é criado sob o modelspasta do aplicativo. O nome do arquivo seria“dynamic_search.py”.

def build_query(field, op, value):
   if op == 'equals':
      return field == value
   
   elif op == 'not equal':
      return field != value
   
   elif op == 'greater than':
      return field > value
   
   elif op == 'less than':
      return field < value
   
   elif op == 'starts with':
      return field.startswith(value)
   
   elif op == 'ends with':
      return field.endswith(value)
   
   elif op == 'contains':
      return field.contains(value)

def dynamic_search(table):
   tbl = TABLE()
   selected = []
   ops = ['equals', 
      'not equal',
      'greater than',
      'less than',
      'starts with',
      'ends with',
      'contains']
		
query = table.id > 0

for field in table.fields:
   chkval = request.vars.get('chk'+field,None)
   txtval = request.vars.get('txt'+field,None)
   opval = request.vars.get('op'+field,None)
	
row = TR(TD(INPUT(_type = "checkbox",_name = "chk"+field,value = chkval == 'on')),
   TD(field),TD(SELECT(ops,_name = "op"+field,value = opval)),
   TD(INPUT(_type = "text",_name = "txt"+field,_value = txtval)))
	
tbl.append(row)

if chkval:
   if txtval:
      query &= build_query(table[field], opval,txtval)
      selected.append(table[field])
      form = FORM(tbl,INPUT(_type="submit"))
      results = db(query).select(*selected)
   return form, results

Controlador

O arquivo associado é “dynamic_search.py” na seção de controladores incluirá o seguinte código -

def index():
   form,results = dynamic_search(db.things)
   return dict(form = form,results = results)

Visão

Podemos renderizar isso com a seguinte visão.

{{extend 'layout.html'}}
{{= form}}
{{= results}}

Aqui está o que parece -