Django model self many-to-many relation
<p>The provided code defines two classes: <code>Folder</code> and <code>FolderParent</code>. Let's go through each class and understand their functionalities:</p> <ol> <li> <p><code>Folder</code> class:</p> <ul> <li>It inherits from the <code>Timestamped</code> class (not …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | class Folder(Timestamped):
name = models.CharField(max_length=50)
depth = models.PositiveIntegerField(default=0)
parents = models.ManyToManyField("self", through='FolderParent',
through_fields=('source', 'target'),
symmetrical=False, blank=True)
class Meta:
default_related_name = 'folders'
verbose_name = 'folder'
verbose_name_plural = 'folders'
def __str__(self):
return f"{self.name}"
def get_depth(self):
"""
Recursively calculates the depth of the folder in the tree structure.
"""
depth = 0
# Traverse up the tree to the root node
parent_folders = self.parents.all()
while parent_folders:
depth += 1
parent_folder = parent_folders.first()
parent_folders = parent_folder.parents.all()
if depth != self.depth:
self.depth = depth
self.save()
return depth
def get_ancestors(self):
"""
Recursively gets a list of ancestor folders in the tree structure.
"""
ancestors = []
parent_folders = self.parents.all()
while parent_folders:
parent_folder = parent_folders.first()
ancestors.append(parent_folder)
parent_folders = parent_folder.parents.all()
return reversed(ancestors)
def get_breadcrumb(self):
"""
Returns a list of ancestor folders and the current folder,
representing the breadcrumb for the current folder.
"""
breadcrumb = list(self.get_ancestors())
breadcrumb.append(self)
return breadcrumb
class FolderParent(Timestamped):
source = models.ForeignKey(Folder, on_delete=models.CASCADE,
related_name='folder_parent')
target = models.ForeignKey(Folder, on_delete=models.CASCADE,
related_name='folder_child')
class Meta:
constraints = [
models.UniqueConstraint(fields=['source', 'target'], name="folderparent")
]
indexes = [
models.Index(fields=['source', 'target']),
]
|