⇤ ← Revision 1 as of 2010-08-01 20:39:28
3855
Comment:
|
3951
|
Deletions are marked like this. | Additions are marked like this. |
Line 3: | Line 3: |
Collections are a way to manipulating a group of objects as one. | Collections are a way of selecting a group of object based on some criteria, and then either just getting the objects, or possibly manipulating the set as one. |
Collections
Collections are a way of selecting a group of object based on some criteria, and then either just getting the objects, or possibly manipulating the set as one.
They have two types of methods on them, firstly restrict methods, which reduce the set of objects according to some criteria, and secondly manipulating methods, which may act on the current set.
Examples
BranchCollection - lp.code.{model,interfaces}.branchcollection
TranslationTemplatesCollection - lp.translations.{model,interfaces}.potemplate
ArchiveCollection - lp.soyuz.{model,interfaces}.archivecollection
Example use
all_branches = getUtility(IAllBranches) my_branches = all_branches.ownedBy(me) branches_i_can_see = all_branches.visibleByUser(me) merge_proposals_on_my_branches = my_branches.getMergeProposals() my_branch_objects = my_branches.getBranches()
Creating a collection
In lp.services.database.collection there is a base class you can use for creating your own collection.
In lp.app.model.foocollection add
from lp.app.model.foo import Foo from lp.services.database.collection import Collection class FooCollection(Collection): starting_table = Foo
Which is the basic collection.
You can then add methods to it such as
def ownedBy(self, owner): return self.refine(Foo.owner == owner)
with appropriate tests (see lp.soyuz.tests.test_archivecollection for some inspiration).
Once you have an object with the methods that will be useful to you, you need to add an interface and a utility.
In lp.app.interfaces.foocollection add the following:
from zope.interface import Interface class IFooCollection(Interface):
with the methods you want on the interface. Ensure that one of the methods you put on the interface is
def select(*args):
As this is what will be used to get the ResultSet.
Once you have that you can add an Interface for getting a utility to get all Foos
class IAllFoos(IFooCollection): """Get all foos."""
You can add other marker interfaces here if you wish to provide other entry points, for instance if it is very common to be interested in all foos of a particular type or status.
Next comes the zcml:
<securedutility class="lp.app.model.foocollection.FooCollection" provides="lp.app.interfaces.foocollection.IAllFoo"> <allow interface="lp.app.interfaces.foocollection.IAllFoo" /> </securedutility> <class class="lp.app.model.foocollection.FooCollection"> <allow interface="lp.app.interfaces.foocollection.IAllFoo" /> </class>
Which will mean that you can getUtility(IAllFoo) to start working with a collection.
Using the collection
all_foos = getUtility(IAllFoo) foos = all_foos.ownedBy(person).withStatus(status).select()
The arguments to select are the same as the first argument to Store.find().
Adding adapters
It is possible to add adapters for objects of interest to get a collection initialized as appropriate.
For instance you could add adapters such that
IFooColllection(product)
returned you a FooCollection for all the Foos associated with that product.
Please fill in the details of how to do this here if you do it.
Adding Joins
Please fill in the details of how to join tables here if you work it out.