Web2py - 核心

命令行选项

我们在上一章中学习了如何使用 GUI 小部件启动 web2py 服务器。

可以通过从命令行提示符启动服务器来跳过此小部件。

python web2py.py -a 'your password' -i 127.0.0.1 -p 8000

每当 web2py 服务器启动时,它都会创建一个文件"parameters_8000.py",其中所有密码都以哈希形式存储。

出于额外的安全目的,可以使用以下命令行 −

python web2py.py -a '<recycle>' -i 127.0.0.1 -p 8000

对于上述场景,web2py 重用存储在"parameters_8000.py"中的哈希密码。

如果文件"parameters_8000.py"被意外删除或由于其他原因,则 web2py 中基于 Web 的管理界面将被禁用。

URL 映射/调度

web2py的功能基于模型-视图-控制器,它将URL映射为特定的形式 − http://127.0.0.1:8000/a/d/f.html

它路由直到控制器d.py中提到的函数"f()"位于名为"a"的应用程序下。 如果应用程序中不存在该控制器,则 web2py 使用名为 "default.py" 的默认控制器。

如果 URL 中给定的函数不存在,则使用名为 init() 的默认函数。 下图示意性地显示了 URL 的工作原理。

函数初始化

URL 的扩展名 .html 是可选的。 扩展名决定了 View 的扩展名,该扩展名呈现控制器中定义的函数的输出。 相同的内容以多种格式提供,即 html、xml、json、rss 等。

根据函数传递请求,函数接受参数并向用户提供适当的输出。 它是控制器,与应用程序的模型和视图交互,根据用户的需要提供输出。

web2py – 工作流程

下面讨论web2py的工作流程 −

  • Web 服务器在自己的线程中同时管理每个 HTTP 请求。

  • HTTP 请求标头被解析并传递给调度程序。

  • 调度程序管理应用程序请求并将 PATH_INFO 映射到函数调用的 URL 中。 每个函数调用都在 URL 中表示。

  • 对静态文件夹中包含的文件的所有请求都直接管理,大文件会流式传输到客户端。

  • 对除静态文件之外的任何内容的请求都会映射到操作中。

  • 如果请求标头包含应用程序的会话 cookie,则检索会话对象; 否则,将创建一个会话 ID。

  • 如果操作返回字符串值,则该值将返回给客户端。

  • 如果操作返回一个可迭代对象,则它用于循环并将数据流式传输到客户端。

条件模型

在上一章中,我们了解了控制器的功能。 web2py 在其每个应用程序中使用模型、视图和控制器。 因此,了解Model的功能也是很有必要的。

与任何其他 MVC 应用程序不同,web2py 中的模型被视为有条件的。 根据控制器的使用情况执行子文件夹中的模型。 这可以用下面的例子来证明 −

考虑 URL − http://127.0.0.1:8000/a/d/f.html

在本例中,'a' 是应用程序的名称,'d' 是控制器的名称,f() 是与控制器关联的函数。 将执行的模型列表如下 −

applications/a/models/*.py
applications/a/models/d/*.py
applications/a/models/d/f/*.py

web2py 包含库,这些库作为对象公开给所有应用程序。 这些对象在名为"gluon"的目录下的核心文件中定义。

许多模块(例如DAL模板)没有依赖关系,可以在web2py框架之外实现。 它还维护被认为是良好实践的单元测试。

应用程序

web2py 应用程序如下图所示。

图表形式

用web2py开发的应用程序由以下部分组成 −

  • Models − 代表数据和数据库表。

  • Controllers − 描述应用程序逻辑和工作流程。

  • Views − 帮助渲染数据的显示。

  • Languages − 描述如何将应用程序中的字符串翻译成各种支持的语言。

  • Static files − 不需要处理(例如图像、CSS 样式表等)。

  • ABOUT and README − 项目详情。

  • Errors − 存储应用程序生成的错误报告。

  • Sessions − 存储与每个特定用户相关的信息。

  • Databases − 存储 SQLite 数据库和附加表信息。

  • Cache − 存储缓存的应用程序项目。

  • Modules − 模块是其他可选的 Python 模块。

  • Private − 包含的文件可由控制器访问,但不能直接由开发人员访问。

  • Uploads − 文件由模型访问,但开发人员不能直接访问。

API

在 web2py 中,模型控制器视图在为开发人员导入某些对象的环境中执行。

全局对象 − 请求、响应、会话、缓存。

Helpers − web2py 包含帮助程序类,可用于以编程方式构建 HTML。 它对应于 HTML 标签,称为 "HTML 助手"

例如A、B、FIELDSET、FORM等

会话

会话可以定义为服务器端信息存储,该信息在整个 Web 应用程序的用户交互过程中持续存在。

web2py中的Session是存储类的实例。

例如,变量可以存储在会话中:

session.myvariable = "hello"

该值可以检索为

a = session.myvariable

只要同一用户在同一会话中执行该代码,就可以检索该变量的值。

web2py 中用于会话的重要方法之一是"forget"

session.forget(response);

它指示 web2py 不要保存会话。

在后台运行任务

HTTP 请求到达 Web 服务器,Web 服务器在自己的线程中并行处理每个请求。 活动的任务在前台进行,而其他任务则在后台进行。 管理后台任务也是 web2py 的主要功能之一。

耗时的任务最好保留在后台。 下面列出了一些管理后台任务的机制 −

  • CRON

  • 队列

  • 调度程序

CRON

在 web2py 中,CRON 提供了在指定的时间间隔内运行任务的能力。 每个应用程序都包含一个 CRON 文件,它定义了其功能。

调度程序

内置调度程序通过设置优先级帮助在后台运行任务。 它提供了创建、调度和修改任务的机制。

计划的事件在文件名"scheduler.py"的模型中列出。

构建应用程序

我们概述了在 web2py 中创建模型和控制器。 在这里,我们将重点关注名为"Contacts"的应用程序的创建。 该应用程序需要维护一个公司列表以及在这些公司工作的人员列表。

创建模型

这里,数据字典的表的标识就是模型。 联系人应用程序的模型将在"models"文件夹下创建。 该文件存储在models/db_contacts.py中。

# in file: models/db_custom.py
db.define_table('company', Field('name', notnull = True, unique = True), format = '%(name)s')
db.define_table(
   'contact',
   Field('name', notnull = True),
   Field('company', 'reference company'),
   Field('picture', 'upload'),
   Field('email', requires = IS_EMAIL()),
   Field('phone_number', requires = IS_MATCH('[\d\-\(\) ]+')),
   Field('address'),
   format = '%(name)s'
)

db.define_table(
   'log',
   Field('body', 'text', notnull = True),
   Field('posted_on', 'datetime'),
   Field('contact', 'reference contact')
)

创建上述文件后,可以通过 URL http://127.0.0.1:8000/contacts/appadmin

访问表格

创建控制器

控制器将包括一些用于列出、编辑和删除联系人的功能。

# in file: controllers/default.py
def index():return locals()
def companies():companies = db(db.company).select(orderby = db.company.name)
return locals()

def contacts():company = db.company(request.args(0)) or redirect(URL('companies'))
contacts = db(db.contact.company == company.id).select(orderby = db.contact.name)
return locals()

@auth.requires_login()
def company_create():form = crud.create(db.company, next = 'companies')
return locals()

@auth.requires_login()
def company_edit():company = db.company(request.args(0)) or redirect(URL('companies'))
form = crud.update(db.company, company, next='companies')
return locals()

@auth.requires_login()
def contact_create():db.contact.company.default = request.args(0)
form = crud.create(db.contact, next = 'companies')
return locals()

@auth.requires_login()
def contact_edit():contact = db.contact(request.args(0)) or redirect(URL('companies'))
form = crud.update(db.contact, contact, next = 'companies')
return locals()

def user():return dict(form = auth())

视图的创建及其输出将在下一章中讨论。