Web2py - 表单与验证器



web2py 提供了强大的表单生成功能。在 web2py 中构建表单有四种不同的方法,如下所示:

  • FORM - 就 HTML 辅助函数而言,它被认为是低级实现。FORM 对象知道其字段内容。

  • SQLFORM - 它为现有数据库提供创建、更新和删除的功能。

  • SQLFORM.factory - 它被认为是 SQLFORM 之上的抽象层,它生成类似于 SQLFORM 的表单。在这里,不需要创建新的数据库。

  • CRUD 方法 - 顾名思义,它提供了创建、检索、更新和删除功能,其功能基于 SQLFORM。

FORM

考虑一个应用程序,它接受用户的输入,并有一个“提交”按钮来提交响应。

控制器

“default.py”控制器将包含以下关联函数

def display_form():
   return dict()

视图

关联的视图“default/display_form.html”将以 HTML 形式呈现表单的显示,如下所示:

{{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)}}

以上示例是普通的 HTML 表单,它要求用户输入。可以使用 FORM 对象等辅助函数生成相同的表单。

控制器

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

“default.py”控制器中的上述函数包含 FORM 对象(HTML 辅助函数),它有助于创建表单。

视图

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

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

{{= BEAUTIFY(request.vars)}}

由语句{{= form}}生成的表单会序列化 FORM 对象。当用户填写表单并单击提交按钮时,表单会自行提交,并且变量request.vars.value及其输入值将显示在底部。

SQLFORM

它有助于为现有数据库创建表单。下面讨论了其实现步骤。

使用 DAL 建立与数据库的连接,这是使用 DAL 对象创建的,也称为 DAL 构造函数。建立连接后,用户可以创建相应的表。

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

因此,我们创建了一个名为“employee”的表。控制器使用以下语句构建表单和按钮:

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

因此,对于创建的 employee 表,控制器中的修改将为:

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

视图没有修改。在新控制器中,有必要构建一个 FORM,因为在模型中定义的 SQLFORM 构造函数从表 db.employee 构建了一个 FORM。新表单序列化后,显示如下:

<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>

表单中的所有标签都具有从表和字段名称派生的名称。

SQLFORM 对象还可以处理“上传”字段,方法是将上传的文件保存在“uploads”文件夹中。这是自动完成的。SQLFORM 使用复选框显示“布尔”值,并使用“textareas”显示文本值。

SQLFORM 还使用 process 方法。如果用户希望保留与关联的 SQLFORM 关联的值,则需要此方法。

如果form.process(keepvalues = True),则会被接受。

示例

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

有时,用户需要以一种存在现有数据库表但没有实现数据库的方式生成表单。用户只是想利用 SQLFORM 的功能。

这是通过form.factory完成的,它保存在会话中。

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)

表单将显示为 SQLFORM,其字段为名称和图像,但数据库中不存在这样的表。

“default/form_from_factory.html”视图将表示为:

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

CRUD 方法

CRUD 是在 SQLFORM 之上使用的 API。顾名思义,它用于创建、检索、更新和删除相应的表单。

与 web2py 中的其他 API 相比,CRUD 没有公开;因此,有必要导入它。

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

上面定义的 CRUD 对象提供了以下 API:

序号 API 与功能
1

crud.tables()

返回数据库中定义的表列表。

2

crud.create(db.tablename)

返回表 tablename的创建表单。

3

crud.read(db.tablename, id)

返回tablename和记录 id 的只读表单。

4

crud.delete(db.tablename, id)

删除记录

5

crud.select(db.tablename, query)

返回从表中选定的记录列表。

6

crud.search(db.tablename)

返回一个元组 (form, records),其中 form 是搜索表单。

7

crud()

根据 request.args() 返回上述内容之一。

表单创建

让我们创建一个表单。请遵循以下代码。

模型

在应用程序的models文件夹下创建一个新模型。文件名为“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

控制器

控制器部分中的关联文件“dynamic_search.py”将包含以下代码:

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

视图

我们可以使用以下视图呈现它。

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

它看起来像这样:

View
广告