我在思考我的 Pyramid 网络应用程序时遇到了问题。我的结构非常像 Michael Merickel 描述的结构 here ,除了我使用纯遍历来查找我的观点。 (它们被声明为配置了 context='path.toResource' name='myView'),根据我从 traversal wiki tutorial. 中可以看出的相当标准的票价不过,我的应用程序具有更复杂的 URL 结构:我的用户资源位于 /users/{user_id}
下,我的项目位于 /projects/{project_id}
下。我的所有资源都使用 SQLAlchemy ORM 进行持久化;我有一个带有 __name__
和 __parent__
属性的 User 和 Project 类,以及其他扩展 Columns 的属性。
class User(Base):
id = Column(...)
__name__ = None
__parent__ = None
Class Project(Base):
id = Column(...)
__name__ = None
__parent__ = None
owner_id = Column(...ForeignKey(User.id))
owner = relationship(User,...)
我有一个 RootFactory、ProjectFactory 和 UserFactory,它们在它们的 __get_item__
调用中填充了适当的 __name__
和 __parent__
属性。
因此,在 Project 上下文的 View 函数中,我在 request.context 中获得了一个 Project 实例。我的问题是我到底如何引用相应的用户实例?我不能做 project.owner,因为那个 User 实例没有通过 RootFactory 链,所以它的 __parent__
和 __name__
值是未设置的。这很糟糕,因为我想使用 request.resource_url 找到所有者用户的 URL,所以我可以在 View 页面上放置一个链接。
这里的解决方案是什么?我是否通过 request.root 做一切?如果我想进行返回 User 或 Project 实例的复杂查询怎么办?是否有某种 CrapFactory 可以传递给 SQLAlchemy,以便它的所有实例都能正确填充?
我的方法完全错误吗?
我觉得如果我坚持使用 URL 路由,我就不会遇到这些问题......
最佳答案
这是每个人在尝试将 SQLAlchemy 与遍历混合时都会遇到的问题。遍历的一个要求是拥有一个持久的树结构,您可以遍历它以从一个节点到达另一个节点。
您基本上有 2 个选择。
您可以在数据库中构建一个实际的树,每个资源都知道它所在的位置。因此,当您加载资源时,它可以通过某种方式确定其父资源和名称。这是最好的选择。这通常是通过在数据库中创建一个自引用资源表来完成的。然后你的
User
和Project
对象都会有resource_id
外键,它们可以用来确定它们在树中的位置。当前仅当您从根部遍历树时才会填充您的姓名和父级,因此您可以通过
request.root
执行所有操作以引用树的其他部分。
也可以只在每个资源上定义一个 __resource_url__
属性,但在大多数情况下这也相当老套。
需要指出的是,说“我的 URL 具有这种结构”与实际构建您可以使用的该结构的持久层次结构有很大区别。处理 URL 相当简单,但如果没有持久树,生成它们可能会很痛苦。
关于python - SQLAlchemy 和 Pyramid,如何从上下文中获取资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8427902/