Diff for "Collections"

Not logged in - Log In / Register

Differences between revisions 1 and 2
Revision 1 as of 2010-08-01 20:39:28
Size: 3855
Editor: james-w
Comment:
Revision 2 as of 2010-08-01 20:52:09
Size: 3951
Editor: james-w
Comment:
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

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.

Collections (last edited 2019-10-04 11:27:35 by cjwatson)