What's new? | Help | Directory | Sign in
Google
django-mptt
Utilities for implementing Modified Preorder Tree Traversal
  
  
  
  
    
Search
for
Updated Jan 24, 2008 by jonathan.buchanan
Labels: Featured
BackwardsIncompatibleChanges  
Backwards-incompatible changes to Django MPTT since the 0.1 release.

This page lists backwards-incompatible changes to Django MPTT since the 0.1 release.

Changes made after Django MPTT 0.1

Revision 77: Model registration changed

Registering a model for MPTT is now handled by calling mptt.register instead of mptt.models.treeify.

Revision 41: Simplified the node movement API

TreeManager.move_node is now the only public means of moving a node using TreeManager - it can figure out what to do based on the node and target given. All other node movement methods which were previously documented as public have been renamed to begin with underscores, indicating that they are for internal use.

This also has the benefit of simplifying implementation somewhat, as the methods which actually do the moving can trust move_node to give them the correct types of nodes when it matters that a given node must be a root node or a child node.

Changes made after Django MPTT 0.2

Revision 100: Implemented ordering by multiple fields upon insertion

The order_insertion_by argument to mptt.register must now be a list or other iterable of field names.

Old format:

mptt.register(MyModel, order_insertion_by='name')

New format:

mptt.register(MyModel, order_insertion_by=['name'])

Comment by cardhuenator, Jul 16, 2008

Hello, I had to deploy my app on a python2.3 box. The only incompatibility I found was on the itertools.tee function on utils.py to which I copied down its implementation down on the code.

I suggest a django.utils.itercomp approach:

if hasattr(itertools, 'tee'):
  tee = itertools.tee
else:
  from mppt.itercompat import tee

The orginal itertools.tee() implementation, I believe:

class TeeData(object):
    """Holds cached values for TeeObjects"""
    def __init__(self, iterator):
        self.data = []
        self._iter = iterator

    def __getitem__(self, i):
        # iterates until 'i' if not done yet
        while i>= len(self.data):
            try:
                self.data.append( self._iter.next() )
            except AttributeError:
                # CPython raises a TypeError when next() is not defined
                raise TypeError('%s has no next() method' % self._iter)
        return self.data[i]


class TeeObject(object):
    """Iterables / Iterators as returned by the tee() function"""
    def __init__(self, iterable=None, tee_data=None):
        if tee_data:
            self.tee_data = tee_data
            self.pos = 0
        # <=> Copy constructor
        elif isinstance(iterable, TeeObject):
            self.tee_data = iterable.tee_data
            self.pos = iterable.pos
        else:
            self.tee_data = TeeData(iter(iterable))
            self.pos = 0
            
    def next(self):
        data = self.tee_data[self.pos]
        self.pos += 1
        return data
    
    def __iter__(self):
        return self

    
def tee(iterable, n=2):
    """Return n independent iterators from a single iterable.
    Note : once tee() has made a split, the original iterable
    should not be used anywhere else; otherwise, the iterable could get
    advanced without the tee objects being informed.
    
    Note : this member of the toolkit may require significant auxiliary
    storage (depending on how much temporary data needs to be stored).
    In general, if one iterator is going to use most or all of the
    data before the other iterator, it is faster to use list() instead
    of tee()
    
    Equivalent to :
    
    def tee(iterable, n=2):
        def gen(next, data={}, cnt=[0]):
            for i in count():
                if i == cnt[0]:
                    item = data[i] = next()
                    cnt[0] += 1
                else:
                    item = data.pop(i)
                yield item
        it = iter(iterable)
        return tuple([gen(it.next) for i in range(n)])
    """
    if isinstance(iterable, TeeObject):
        # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c)
        return tuple([iterable] +
        [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)])
    tee_data = TeeData(iter(iterable))
    return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)])

Sign in to add a comment