zope 3的关系域框架。
z3c.relationfield的Python项目详细描述
z3c.关系字段
简介
这个包实现了一个新的schema字段关系,并且 存储实际关系的RelationValue对象。它可以索引这些 使用基础结构的关系 索引可以有效地回答有关关系的问题。
该包还提供了一个小部件 编辑并显示关系字段。
设置
z3c.relation field.relation 是一个架构字段,可用于 表达关系。让我们定义一个使用关系的模式项 字段:
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")
我们还定义了一个类 项 以及特殊的 z3c.relationfield.interfaces.ihasrelations 接口:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None
需要使用 ihasrelations 标记接口 在 项被编目(当它们被放入容器并被移除时 例如,从中)。它实际上是 iHasInComingRelations 和 iHasOutgoingRelations ,这很好 因为我们希望项目同时支持这两者。
最后,我们需要一个测试应用程序:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass
我们设置了测试应用程序:
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)
我们确保这是当前站点,这样我们就可以查找本地 它的实用程序等等。通常这是由 Zope的遍历机制:
>>>fromzope.site.siteimportLocalSiteManager>>>root.setSiteManager(LocalSiteManager(root))>>>fromzope.component.hooksimportsetSite>>>setSite(root)
要使此站点与z3c.relationship一起工作,我们需要设置两个 公用事业。首先,一个跟踪对象唯一id的 IIntids 在zodb中:
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)
其次是一个实际索引关系的关系目录:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)
使用关系字段
我们将在应用程序中添加一个项目 a :
>>>root['a']=Item()
所有项目,包括我们刚刚创建的项目,都应该具有唯一的int ID,因为链接到它们需要此ID:
>>>fromzopeimportcomponent>>>fromzope.intid.interfacesimportIIntIds>>>intids=component.getUtility(IIntIds)>>>a_id=intids.getId(root['a'])>>>a_id>=0True
当前关系为"无" :
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")0
现在我们可以创建一个链接到item a 的item b (通过 int id):
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")1
我们现在将 b 对象存储在一个容器中,该容器还将设置 它的关系(作为iobjectaddedevent将被触发):
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")2
让我们来看看这段关系。首先,我们将检查 指向对象('b')此关系指向的是:
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")3
我们可以要求它指向的对象:
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")4
我们还可以得到做指向的对象;因为我们 提供了 ihasrelations 接口,事件系统很小心 设置这个:
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")5
这个对象也被称为父对象 系统负责设置此项:
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")6
关系还知道两个指向对象的接口 以及被指向的对象:
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")7
我们还可以得到扁平形式的接口:
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")8
路径
我们还可以得到关系的路径(两者都是从它所在的位置 以及它所指向的地方)。路径应该是 对我们所指对象的可读引用,合适的 用于序列化。为了处理路径,我们首先需要设置 上一个 iobjectpath 实用程序。
因为在本例中,我们只将对象放在一个平面根中 容器,本演示中的路径可能非常简单: 只是我们指向的对象的名称。更加复杂 应用程序路径通常是斜线分隔的路径,如 /foo/bar :
>>>fromz3c.relationfieldimportRelation>>>fromzope.interfaceimportInterface>>>classIItem(Interface):...rel=Relation(title=u"Relation")9
之后,我们可以得到关系指向的对象的路径:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None0
我们还可以得到正在进行指向的对象的路径:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None1
比较和排序关系
我们来吧吃一堆 relationvalue 对象并比较它们:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None2
关系当然等于它们自己:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None3
已存储的关系等于尚未存储的关系:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None4
我们还可以对关系进行排序:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None5
关系查询
现在我们已经建立了 a 和 b ,我们可以使用关系目录发出查询。我们先来 获取目录:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None6
让我们询问目录关于从 b 到 a 的关系:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None7
我们再看一次这个关系对象。我们确实走对了:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None8
请求与 b 的关系将导致一个空列表,因为没有 已建立关系:
>>>fromz3c.relationfield.interfacesimportIHasRelations>>>frompersistentimportPersistent>>>fromzope.interfaceimportimplementer>>>@implementer(IItem,IHasRelations)...classItem(Persistent):......def__init__(self):...self.rel=None9
我们还可以发出更具体的查询,将其限制在 用于关系字段和由提供的接口的属性 相关对象。这里我们寻找 b 和 存储在对象属性rel中并指向 从具有接口的对象到具有 接口项
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass0
没有为其他属性存储关系:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass1
也没有为我们将要介绍的新接口存储关系 这里:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass2
更改关系
让我们创建一个新对象
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass3
现在还没有什么指向 c 的:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass4
我们目前有一个从 b 到 a 的关系:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass5
我们可以将关系改为指向一个新对象
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass6
我们需要发送一个 iobjectmodifiedvent 让目录知道我们 已更改关系:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass7
我们现在应该找到一个从 b 到 c 的单一关系:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass8
与 a 的关系现在应该消失:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass9
如果我们将关系存储在一个非模式字段中,它应该保持 对象修改器。
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)0
删除关系
我们现在有一个从 b 到 c 的关系:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass8
我们可以通过设置一个从 b 到 c 的现有关系 无 :
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)2
我们需要发送一个 iobjectmodifiedvent 让目录知道我们 已更改关系:
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)3
将关系设置为 b 到 无应该删除该关系 从关系目录中,因此我们将无法再找到它:
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)4
让我们重新建立删除的关系:
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)5
复制具有关系的对象
让我们复制一个具有以下关系的对象:
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)6
现在可以找到与 c 的两个关系,一个来自原始的,以及 副本中的另一个:
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)7
关系是可排序的
默认情况下,根据关系名称的组合对关系进行排序, 对象的路径关系是1,对象的路径 关系指向。
让我们现在查询所有可用的关系并对它们进行排序:
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)8
删除具有关系的对象
我们将再次删除b-2。它的关系应该自动删除 从目录中:
>>>fromZODB.MappingStorageimportDB>>>db=DB()>>>conn=db.open()>>>root=conn.root()['root']=TestApp()>>>conn.add(root)9
打破关系
我们现在有一个从 b 到 c 的关系:
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass8
我们没有断绝关系:
>>>fromzope.site.siteimportLocalSiteManager>>>root.setSiteManager(LocalSiteManager(root))>>>fromzope.component.hooksimportsetSite>>>setSite(root)1
关系没有破裂:
>>>fromzope.site.siteimportLocalSiteManager>>>root.setSiteManager(LocalSiteManager(root))>>>fromzope.component.hooksimportsetSite>>>setSite(root)2
我们现在要通过删除 c :
>>>fromzope.site.siteimportLocalSiteManager>>>root.setSiteManager(LocalSiteManager(root))>>>fromzope.component.hooksimportsetSite>>>setSite(root)3
现在关系破裂了:
>>>fromzope.site.siteimportLocalSiteManager>>>root.setSiteManager(LocalSiteManager(root))>>>fromzope.component.hooksimportsetSite>>>setSite(root)4
原始关系仍有一个 到u路径 :
>>>fromzope.site.siteimportLocalSiteManager>>>root.setSiteManager(LocalSiteManager(root))>>>fromzope.component.hooksimportsetSite>>>setSite(root)5
但是,由于没有 to_object :
>>>fromzope.site.siteimportLocalSiteManager>>>root.setSiteManager(LocalSiteManager(root))>>>fromzope.component.hooksimportsetSite>>>setSite(root)6
对…的d 也不见了:
>>>fromzope.site.siteimportLocalSiteManager>>>root.setSiteManager(LocalSiteManager(root))>>>fromzope.component.hooksimportsetSite>>>setSite(root)7
我们在目录中找不到断开的关系,因为它不是 再指向 c\u id :
>>>fromzope.site.siteimportSiteManagerContainer>>>fromzope.container.btreeimportBTreeContainer>>>classTestApp(SiteManagerContainer,BTreeContainer):...pass4
但是,我们可以通过搜索具有 至 无的ID :
>>>fromzope.site.siteimportLocalSiteManager>>>root.setSiteManager(LocalSiteManager(root))>>>fromzope.component.hooksimportsetSite>>>setSite(root)9
断开的关系不等于无(这是个错误):
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)0
关系选择
relationchoice字段与普通的关系字段非常相似 但是可以用来呈现一个特殊的小部件,允许选择 选择。
我们将首先演示relationchoice字段具有相同的效果 作为一个 关系 字段本身:
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)1
让我们创建一个对象,将关系指向:
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)2
让我们建立关系:
<…代码块::python < Buff行情>>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)3
我们现在可以查询此关系:
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)4
关系列表
现在让我们尝试一下可以使用的 relationlist 字段 维护关系列表:
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)5
我们还定义了一个实现 多项目和特殊 z3c.relationfield.interfaces.ihasrelations 接口:
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)6
我们设置了几个对象,然后可以在它们之间创建关系:
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)7
让我们创建一个从 multi1 到 multi2 和 多重3 :
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)8
我们需要通知我们修改了objectmodifiedvent
>>>fromzope.intidimportIntIds>>>fromzope.intid.interfacesimportIIntIds>>>root['intids']=intids=IntIds()>>>sm=root.getSiteManager()>>>sm.registerUtility(intids,provided=IIntIds)9
现在已经设置好了,让我们验证是否可以找到 目录中的正确关系:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)0
临时关系
如果我们有一个进口程序 外部源(如XML文件),可能是我们读取了一个关系 指向一个尚未存在的对象 进口。我们为此提供一个特殊的时间关系值 案例。a 临时关系值只包含它的路径 指向,但尚未解决。让我们使用 在新对象中创建与 a :
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)1
修改事件实际上并没有将此关系编目:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)2
我们现在将把 d 上的所有临时关系转换为实际关系:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)3
我们现在可以看到真正的关系对象:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)4
关系现在也将显示在目录中:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)5
临时关系值也适用于 关系列表 对象:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)6
让我们将其转换为实际关系:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)7
当我们再次看到真实的关系对象时:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)8
现在我们将看到这个新关系出现在目录中:
>>>fromz3c.relationfieldimportRelationCatalog>>>fromzc.relation.interfacesimportICatalog>>>root['catalog']=catalog=RelationCatalog()>>>sm.registerUtility(catalog,provided=ICatalog)9
中断的临时关系
我们再建立一个临时关系,这次是一个破裂的关系 无法解析:
>>>root['a']=Item()0
让我们试着认识到这种关系:
>>>root['a']=Item()1
我们的关系破裂了:
>>>root['a']=Item()2
它指向不存在的路径:
>>>root['a']=Item()3
设置发布目录
此包提供了一个relationcatalog,它由一组索引初始化,这些索引通常用于查询relationvalue对象。 默认索引是 from_id , to_id , from_attribute , from_interfaces_flated 和 to_interfaces_flated
有时需要定义自定义索引或使用比默认索引少的索引。 zc.relationfield.index.relationcatalog 类可以初始化为一个dict列表,其中包含要传递给relationcatalog addvalueindex 方法的键 element 和 kwargs 。 通常, irelationvalue 上的属性类似于 irelationvalue['from_id']。 但是,如果有一个子类 irelationvalue 与其他字段一起使用,则可以在此处将这些字段添加为索引。