我在Pyramid网络应用程序中缠绕问题。我的结构非常像迈克尔·梅里克尔here描述的结构,除了我使用纯粹的遍历来查找我的观点。 (它们被声明配置为context ='path.toResource'name ='myView'),相当标准的票价根据我可以从traversal wiki tutorial.我可以告诉我的应用程序有一个更复杂的URL结构虽然:我的用户资源是在/users/{user_id}
下,我的项目位于/projects/{project_id}
下。我的所有资源都使用SQLAlchemy ORM保留;我有一个具有__name__
和__parent__
属性的User和Project类,以及扩展列的其他属性。
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,用于填充__name__
次调用中相应的__parent__
和__get_item__
属性。
因此,在Project上下文的视图函数中,我在request.context中获得了一个Project实例。我的问题是如何引用相应的用户实例?我无法执行project.owner,因为该User实例未通过RootFactory链,因此未设置其__parent__
和__name__
值。这很糟糕,因为我想使用request.resource_url来查找所有者User的URL,所以我可以在视图页面上放置一个链接。
这里的解决方案是什么?我是否通过request.root 所有?如果我想创建一个返回User或Project实例的复杂查询,该怎么办?是否有某种CrapFactory我可以传递SQLAlchemy所以它的所有实例都能正确填充?
我的做法完全错了吗?
如果我坚持使用URL路由,我觉得我不会遇到这些问题...
答案 0 :(得分:5)
这是每个人在尝试将SQLAlchemy与遍历混合时遇到的问题。遍历的要求是具有持久的树结构,您可以遍历该结构以从一个节点到另一个节点。
你基本上有两个选择。
您可以在数据库中构建一个实际树,其中每个资源都知道它所在的位置。因此,当您加载资源时,它可以通过某种方式确定其父级和名称。这是最好的选择。这通常通过在数据库中创建自引用资源表来完成。然后,您的User
和Project
对象都会有resource_id
个外键,可用于确定它们在树中的位置。
当您从根遍历树时,目前只填充您的姓名和父级,因此您可以通过request.root
执行所有操作,以便引用树的其他部分。
也可以在每个资源上定义一个__resource_url__
属性,但对于大多数情况来说这也是相当苛刻的。
要带走的是,与“我的网址具有此结构”并且实际构建可以使用的该结构的持久层次结构存在很大差异。为了处理URL,它非常简单,但是为了生成它们,没有持久树就会很痛苦。