How it works...
Steps 1 and 2 create the new model with hierarchic relations. The Many2one relation adds a field to reference the parent record. For faster child record discovery, this field is indexed in the database using the index=True parameter. The parent_id field must have ondelete set to either 'cascade' or 'restrict'.
At this point, we have all that is required to have a hierarchic structure, but there are a few more additions we can make to enhance it.
The One2many relation does not add any additional fields to the database, but provides a shortcut to access all the records with this record as their parent.
In step 3, we activate the special support for hierarchies. This is useful for high-read but low-write instructions, since it brings faster data browsing at the expense of costlier write operations. It is done by adding two helper fields, parent_left and parent_right, and setting the model attribute to _parent_store=True. When this attribute is enabled, the two helper fields will be used to store data in searches in the hierarchic tree.
By default, it is assumed that the field for the record's Parent is called parent_id, but a different name can be used. In that case, the correct field name should be indicated using the additional model attribute—_parent_name. The default is as follows:
_parent_name = 'parent_id'
Step 4 is advised in order to prevent cyclic dependencies in the hierarchy, that is, having a record both in the ascending and descending trees. This is dangerous for programs that navigate through the tree, since they can get into an infinite loop. The models.Model provides a utility method for this (_check_recursion) that we have reused here.