djangodjango-modelsforeign-keysdjango-select-relateddjango-related-manager

How to find all related items of django foreign key with multi level self relationships?


Given a model:

class Example(models.Model):
    name = models.CharField(max_length=50, blank=True)
    master= models.ForeignKey('Example', on_delete=models.PROTECT, blank=True, null=True)

With this model, it is possible to have an "Example" without any master, or an "Example" can have a master value which is another "Example". Of course, that master "Example" could be foreign-key'ing another "Example". There is no theoretical limit of foreign-key levels.

What is the best way to get all related items for an item, including masters of it's "master"?

For example, if one creates a "child" child=Example(name="Child") and a mother mother=Example(name="mother", master=child), and finally a grandmother, grandmother = Example(name="grandmother", master=mother), the command child.example_set.all() only returns the mother. How to get all related items including the grandmother in this example?


Solution

  • Based on your example in your question, you are describing a tree in which you are flattening it in your database. Personally, I'd implement trees using something like MPTT (Modified Preorder Tree Traversa) or MP (Materialized Path) over implementing my own implementation.

    There a few great libraries to implement trees in Django -- see django-mptt (MPTT) or django-treebeard (MP). I would suggest looking at the Treebeard tutorial as a first step.