一种对对象系统的url分派,它结合了路由和遍历的各个方面。

traject的Python项目详细描述


悲剧

简介

在web应用程序构建中,有两种主要的发布方式 对象到Web:路由和遍历。两者都是url的一种形式 分派:最后,调用函数或方法的结果是 URL中的模式。两种方法都有很大的不同, 但是。

路由中,从url模式到控制器(或 视图)调用以生成呈现的网页。网址 模式还用于从 然后可以传递。

例如url departments/10/employees/17 。URL 可能存在映射所有部门/*/employees/*的模式。 特定可调用的模式。此外,路由系统可以 用于声明参数 10` 17 应 从这个url获取并作为参数传递给 控制器。然后,程序员对控制器进行编程以检索 使用此信息从数据库中更正模型。此后 控制器使用这些模型中的信息来构造 视图的内容,例如用html呈现 模板。

遍历中,没有到控制器或 意见。相反,模型结构是在 URL。类似地,在python中可以遍历嵌套的 字典( d['a']['b']['c'] ),或属性( d.a.b.c )。在 最后,a 视图 将查找可以 打电话。视图可以是模型的特殊属性。更多 复杂的系统可用于将视图与模型分开。

url departments/10/employees/17 将被解析为一个视图 因为有一个包含 部门 模型对象。依次从a 部门 模型1 可以遍历到 employees 容器,从而允许 遍历到单个雇员,例如雇员17。最后一个 查找17号员工的视图,然后调用该视图。

路由通常与关系数据库结合使用, 通常通过对象关系映射器暴露给对象。 对于内存中的对象结构,遍历往往更方便。 或对象数据库。

路由有以下优点:

  • 这是一种公开关系内容的好方法 自然嵌套。
  • 模式注册表为开发人员提供了 应用程序中的URL模式。
  • 这种方法在许多框架中都很常见。

遍历也有优点:

  • 它是公开具有任意性的对象内容的好方法 嵌套。
  • 模型驱动:对象带有它们的视图。这允许 由模型组成应用程序的开发人员,支持 陈述性方法。
  • 位置感知:可以很容易地创建嵌套的对象结构 位置感知。每个模型都可以在 URL。这样可以方便地为任意 模型。此外,可以基于此声明权限 结构。

traject尝试在 单一系统。Traject:

  • 看起来像一个路由系统并且熟悉路由 接近。
  • 很适合公开关系模型。
  • 允许开发人员显式声明URL映射。
  • 支持任意嵌套,因为可以嵌套URL映射,并且 系统也很容易与正常的遍历相结合。
  • 是模型驱动的。路由是到模型,而不是到视图或控制器。
  • 位置感知。模型处于嵌套结构中,并且知道 它们的父级和名称,允许基于模型的安全声明 e模型的简易URL构造。

traject的一些潜在缺点是:

  • 悲惨的事物期望它的模式有一定的规律性。它没有 允许某些包含多个变量的复杂url模式 单步(即 foo/<;bar-id>;-<;baz-id>; )。只有一个 每个url段允许变量。
  • Traject需要为中的每个阶段构造或检索模型 用来构造嵌套结构的路由。这可能意味着 每个请求对数据库的更多查询。实际上,这通常是 由于结构中的父模型 视图逻辑通常需要。
  • 在traject中,每个模型实例应该只有一个位置 在url结构中。这不仅允许将url解析为 模型,以及要为模型生成的url。如果你想 可以通过多个url访问同一个模型 有些困难。

URL模式

让我们考虑一个url模式字符串,它是一系列步骤 用斜线隔开:

>>> pattern_str = 'foo/bar/baz'

我们可以使用 parse将其分解为组件步骤 功能:

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')

步骤也可能是变量。变量是以 冒号( ):

>>> traject.parse('foo/:a/baz')
('foo', ':a', 'baz')

模式中允许有多个变量步骤:

>>> traject.parse('foo/:a/baz/:b')
('foo', ':a', 'baz', ':b')

模式中的变量名必须是唯一的:

>>> traject.parse('foo/:a/baz/:a')
Traceback (innermost last):
  ...
ParseError: URL pattern contains multiple variables with name: a

注册模式

在traject中,url路径的解析会产生一个模型。这个 然后,模型可以依次为其注册允许此操作的视图 要显示的模型。视图查找的工作方式取决于web 框架本身。

通过注册告诉traject哪个模型返回哪个路径 每个url模式的工厂函数。此工厂功能应该 创建或检索模型对象。

factory函数接收每个匹配的 无论哪种模式匹配的变量-工厂的签名 函数应该包含模式中的所有变量 匹配

让我们看一个例子。

这是我们要识别的URL模式:

>>> pattern_str = u'departments/:department_id/employees/:employee_id'

我们可以在这个url模式中看到两个参数: department\u id` 客户id

我们现在定义一个可能存储在数据库中的模型:

>>> class Employee(object):
...   def __init__(self, department_id, employee_id):
...     self.department_id = department_id
...     self.employee_id = employee_id
...   def __repr__(self):
...     return '<Employee %s %s>' % (self.department_id, self.employee_id)

我们为这个url模式定义factory函数,以便 返回此模型的实例。本例中的参数将 部门ID 和员工ID

>>> def factory(department_id, employee_id):
...   return Employee(department_id, employee_id)

在本例中,factory函数只创建一个 employee 对象 在飞行中。在关系数据库的上下文中,它可以 根据提供的参数执行数据库查询。如果 factory返回 none ,这被解释为系统 无法匹配URL:找不到对象。

为了注册这个工厂函数,我们需要一个 模式,因此我们将创建一个:

>>> patterns = traject.Patterns()

需要为特定类注册模式,或者 ( zope.interface )接口。这就是多重模式 可以支持注册中心,每个注册中心都与特定的根目录关联 对象。在这种情况下,我们将注册一个类的模式 根目录

>>> pattern_str = 'foo/bar/baz'
0

我们现在可以注册url模式和工厂:

>>> pattern_str = 'foo/bar/baz'
1

解析路径

我们已经准备好解决问题。路径是url的一部分,例如 foo/bar/baz 。它看起来很像一个图案,但是 变量将已填写。

通过解析路径检索的模型将位于 位置。最终 他们的祖先将是一个特殊的根模型 都解决了。根模型本身不是由模式解析的:它 是解析所有模式的根。

我们创建一个根型号优先:

>>> pattern_str = 'foo/bar/baz'
2

当路径被解析时,从模型到 根也被创建。可能没有特定的工厂功能 已为特定路径注册。在我们目前的注册中 确实存在这样的模式: 部门 部门/:department\u id 而且 部门/部门id/员工都没有工厂 已注册。

这些步骤将为它们注册一个默认的模型。 在解决模式时,我们需要提供一个特殊的默认工厂 它将在需要时生成默认模型。

让我们在这里建立一个默认工厂。工厂功能需要 能够处理任意数量的关键字参数 可能会提供参数:

>>> pattern_str = 'foo/bar/baz'
3

现在我们有了默认工厂,可以尝试解析路径:

>>> pattern_str = 'foo/bar/baz'
4

另一种 解析堆栈的方法允许我们解析堆栈 而不是名称(其中要解析的第一个名称位于 堆栈):

>>> pattern_str = 'foo/bar/baz'
5

转换器

可以在模式中指定转换器。转换器是 将值转换为所需值并引发 如果不可能,则返回valueerror。python中的内置 int 是 转换器的示例。

在模式中指定一个转换器,该模式带有一个额外的冒号,然后 转换器标识符( int 在这种情况下):

>>> pattern_str = 'foo/bar/baz'
6

Traject带有许多内置转换器:

  • Unicode :默认转换器。尝试将输入转换为 Unicode值。如果未指定转换器,它将使用此转换器。
  • str :尝试将输入转换为字符串。
  • int :尝试将输入转换为整数。
  • unicode list :尝试将输入转换为unicode列表 串。输入被分割成 字符。
  • strlist :尝试将输入转换为字符串列表。这个 输入在 字符上分开。
  • intlist :尝试将输入转换为整数列表。这个 输入在 字符上分开。

我们现在注册模式:

>>> pattern_str = 'foo/bar/baz'
7

我们看到该值确实已转换为整数:

>>> pattern_str = 'foo/bar/baz'
8

可以使用 寄存器转换器注册新的转换器 方法。此方法有两个参数:转换器名称和 转换器功能。转换器功能应采用 参数并将其转换为所需的值。如果转换失败,则 应引发值错误。python int 函数是 有效转换器的示例。

位置

traject支持位置的概念。在我们找到一个模型后, 模型接收两个特殊属性:

>>> pattern_str = 'foo/bar/baz'
9
  • 父级:模型的父级。这是一个模型 匹配父路径(没有最后一步的路径)。

父母也会有一个父母,一直到 终极祖先,根。

我们可以查看之前检索到的对象来演示 祖先链:

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')
0

已经为沿途的每个步骤创建了默认对象 直到根。

使用路径

在混合的traject/traversal环境中,例如 查找是通过遍历完成的,能够解析 根据注册的模式直到不再 可能的。其余的步骤并没有被遵循,而是被假定为 以其他方式使用遍历系统。

consume方法将尽可能使用步骤,返回 那些还没有被消耗的步骤,那些被消耗的步骤, 它找到的对象:

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')
1

部门/1/某些视图不能完全使用Y按模式 部门/:部门id/员工/:员工id ,作为 某些视图与预期的员工不匹配

我们可以看到路径的哪些部分无法使用:

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')
2

路径的哪些部分被作为模式的一部分使用:

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')
3

我们设法使用的最后一个对象代表 1

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')
4

方法consume\u stack的作用与stack相同:

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')
5

给模型定位

模型在遍历后自动给出它们的位置。那里 但是,在另一种情况下,给一个对象一个位置可以是 有用的。例如,我们可以从查询中检索一个对象,然后 希望构造指向它的URL,或检查它是否 位置相关权限。因此,Traject也提供 重建对象位置的功能。

为此,我们需要为每个模型注册一个特殊函数 类,它与工厂相反。给定一个模型实例,它 需要返回模式中使用的参数。因此,对于 以下模式:

>>> pattern_str = u'departments/:department_id/employees/:employee_id'

一个给定的模型,我们需要重建论点 部门id 和该模型中的员工id

这是一个为 员工 执行此操作的函数:

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')
7

当我们注册它时,我们还需要提供它可以使用的类 重新构造参数,在本例中, employee

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')
8

现在让我们构造一些员工:

>>> import traject
>>> traject.parse(pattern_str)
('foo', 'bar', 'baz')
9

它没有位置(没有名称或父项):

>>> traject.parse('foo/:a/baz')
('foo', ':a', 'baz')
0

我们现在可以使用 locate 方法来定位它:

>>> traject.parse('foo/:a/baz')
('foo', ':a', 'baz')
1

模型现在将具有 \u name\uu \u parent\uu 属性:

>>> traject.parse('foo/:a/baz')
('foo', ':a', 'baz')
2

全局模式注册表

因为模式注册中心足够聪明来区分 根,在许多情况下,只有一个全局 模式 注册表 是需要的。顶级功能已在 traject 要操作和使用此模式注册表的命名空间:

>>> traject.parse('foo/:a/baz')
('foo', ':a', 'baz')
3

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java Sonarqube测试覆盖率过滤器(jacoco)   java演示文稿将被取消,因为自创建以来显示度量已更改   java为什么Omnifaces Websocket<o:socket>不能与Websphere 9一起使用?   我试图读取java中的xml,但在我的系统中出现了一个错误   java异步支持未启用,即使默认情况下应该启用   java getThreadHandler方法无法从HandlerThread实例访问   带成员函数的多线程Java启动线程   java jar非法参数   java以编程方式注册@Component注释类   正则表达式如何在java中查找字符串中的长双精度数   具有多客户端的java ServerSocket   java JNI不适用于AppKit线程   java如何在用户选择目录元哈希值时输出该值?   java在春季上传阿拉伯文文件时,文件名以XML实体而不是阿拉伯文符号结束   java为什么我们需要在eclipse中作为远程服务器进行调试?   面向java的数据库计算PageRank   java在单击时切换到不同的活动