The mg.orga.tree application

Requires The mg.core.element application.

Django models

digraph tree {
element [shape = "box", label="Element\nmg.core.element"];
directory [shape = "box", label="Directory"];
presence [shape = "box", label="Presence\n(M2M 'through' table)", style="dotted"];

directory -> element [label = "inheritance  ", style="dotted"];
directory -> presence [label = "children_elements"];
presence -> element;
}

mg.orga.tree Application models

In the mg.orga.tree application, purpose is to build a classical file-system-like file tree in the DB. Featues are:

Telling whether an Element is somewhere within in a given directory’s subtree is non-trivial, but mandatory for implementing ACLs. Therefore:

class mg.orga.tree.models.Directory(mg.core.element.models.Element)

This is the only user-oriented model in the mg.orga.tree module. This is an Element conaining other Elements.

children_elements

A queryset conaining all Element objects which are direct descendant of this one, ordered.

children

Many2Many relation to Elements through the Presence mdoel.

end

A timestamp set to the highest contained Element timestamp. Used with timestamp attribute, this can form a (begin, end) couple.

element_count

Count of elements anywhere in the subtree. This is a cache value automatically updated by Presence objects signals. This can be used to display information about the directory when browsing.

This class also implements the ElementContainer protocol:

append(elem, order = None)

Appends an element in the directory. The additional order parameter is not part of the protocol and allows insertion of an element at arbitrary position in the directory.

Parameters:
  • elem – The element to add in the directory
  • order – The index where to insert the element, defaults to last position.

This is a superset of mg.core.element.utils.protocols.ElementContainer.append().

remove(elem)

Removes the element from the directory

Parameters:
  • elem – Element to remove

This is the implementation of mg.core.element.utils.protocols.ElementContainer.remove().

There are also some accessors to elements contained in subtree:

subtree_element_get_random()

This retrieves a random element (excluding directories) contained somewhere in the subtree rooted here. This is used for thumbnail retrieving, where a random element is used as thumbnail.

subtree_media()

This retrieves an Element queryset matching all non-directory elements contained in the subtree.

subtree_elements()

This retrieves an Element queryset matching all elements (even directories) contained in the subtree.

class mg.orga.tree.models.Presence

This is a Many2Many “through” table, adding an ordering constraint for simple presence of an Element in a Directory.

This model should not be directly manipulated. Users should use the append() and remove() methods of Directory instead.

directory

“Parent” side of the relation

element

“Child” side of the relation

order

Number for ordering children in a given parent.

class mg.orga.tree.models.Reacheable

Reacheability is associating a Directory to another Directory, with the constraint there is at least one path from “parent” to “child” throught the tree.

parent

Pointer to the Directory closer to the root of the tree

child

Pointer to the Directory closer to the leaves of the tree

arity

Count of existing paths from parent to child through the tree. Because a directory may be present more than once in another, this may be more than 1.

Management Commands

Ensuring tree coherence

manage.py mg_tree [--rebuild | --check]

Rebuilds the reachability database contained in the mg.orga.tree.

--rebuild

Completely rebuild the reacheability database:

$ ./manage.py mg_tree --rebuild
Deleting all reacheabilities
 1/2, 4 a/Test
done, 3 reacheabilities seen
$
--check

Check the reacheability database, and report inconsistencies:

$ ./manage.py mg_tree --check
Checking all reacheabilities
Spurious: 0 OK: 3
$

Managing Directories

manage.py mg_tree_shell

Provides a shell like Bash, with completion, commands, ...

Sample session:

$ ./manage.py mg.orga.tree_shell
MgTree / # ls
Listing /
Gueule de Guerrier                                 photo      nipo         2011-01-03 07:53:38.447382
Pirates 2011                                       photo      nipo         2011-01-03 07:53:38.463461
MgTree / # mkdir Test
MgTree / # ls
Listing /
Gueule de Guerrier                                 photo      nipo         2011-01-03 07:53:38.447382
Pirates 2011                                       photo      nipo         2011-01-03 07:53:38.463461
Test                                               directory  nipo         2011-01-03 07:53:54.804970

MgTree / # mv Gueule\ de\ Guerrier Test/
Move /Gueule de Guerrier to /Test
MgTree / # mv Pirates\ 2011 Test/
Move /Pirates 2011 to /Test
MgTree / # ls
Listing /
Test                                               directory  nipo         2011-01-03 07:53:54.804970

MgTree / # ls Test/
Listing /Test
Gueule de Guerrier                                 photo      nipo         2011-01-03 07:53:38.447382
Pirates 2011                                       photo      nipo         2011-01-03 07:53:38.463461

MgTree / # ^D
$

Views

mg.orga.tree.views provides a generic view usable for browsing in a tree.

mg.orga.tree.views.path(request, pk_list, root = None, **extra_context)
Parameters:
  • request – A django request object
  • pk_list (str) – A string containing a list of element primary keys, separated by slashes (/), with a trailing slash. Example: 23/41/11/. This is the current path from root.
  • root (mg.orga.tree.models.Directory) – Root of the tree. May be left to None.
  • extra_context – Extra context passed to the template.

This view uses the tree/in_path.html template.

If a root parameter is passed, pk_list is a list of objects rooted inside root. If no root parameter is set, the first contained pk in pk_list must be an element with no parent.

Note

In order to optimize the checking of the elements in the pk_list path, not all the elements are checked for parenting, but only the fact the last item of pk_list exists somewhere in the root‘s subtree is enough to display the view.

Template gets the following variables (plus the extra_context):

root:
The passed root argument
parents:
List of the Element objects corresponding to each pk in pk_list, in order.
object::
The element whose pk is at the end of pk_list.

Note

If there is no root specified and pk_list is empty, this views reverts to the _root() view.

mg.orga.tree.views._root(request)
Parameters:
  • request – A django request object

Internal view transparently called by path() when we are at root.

This view uses the tree/root.html template.

Template gets the following variables:

object_list:
A list of Element having no parents.

URLs

If tree organization is used directly, with no ACL scheme like The mg.acl.tree_token application, your root urls.py should include the mg.orga.tree.urls.