Nested categories not working correctly in Django

I'm working on a project that contains lots of detail and extra information. I need to use nested categories for my navbar, the first time I ran the code, it was working properly but then when I faced a bug at migration and I had to re-create the project again, It isn't working now anymore.

I have two different types of coding for this nested category and none of them works!

class Category(MPTTModel):
name = models.CharField(max_length=30)
slug = models.SlugField(allow_unicode=True, blank=True, null=True,
                        unique=True)
parent = models.ForeignKey('self', default=None, null=True,
                           blank=True, on_delete=models.SET_NULL,
                           related_name='children')
is_child = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)

class Meta:
    verbose_name = _('category')
    verbose_name_plural = _('categories')

def __str__(self):
    return self.name

this first one and this second one:

class Category(MPTTModel):
name = models.CharField(max_length=100)
parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True,
                        related_name="children")
is_child = models.BooleanField(default=False)
slug = models.SlugField(unique=True, null=True, blank=True, allow_unicode=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)

class Meta:
    verbose_name = _('category')
    verbose_name_plural = _('categories')

def __str__(self):
    return self.name

once I create a new category as a child, it must be included in its parent. But nothing happens and it is created just as a separate category. I'll be so glad if you can help me with this.

It is better not to use ORM and MPTT when working with tree

for example:

team = StaffMember.objects.raw('''
WITH RECURSIVE team(id, supervisor) AS (
      SELECT id, supervisor 
      FROM staff_member
      WHERE id = 42
    UNION ALL
      SELECT sm.id, sm.supervisor
      FROM staff_member AS sm, team AS t
      WHERE sm.id = t.supervisor
    )
 SELECT * FROM team
 ''')

or

def get_all_children(self, include_self=True):
table_name = Account.objects.model._meta.db_table
query = (
    "WITH RECURSIVE children (id) AS ("
    f"  SELECT {table_name}.id FROM {table_name} WHERE id = {self.pk}"
    "  UNION ALL"
    f"  SELECT {table_name}.id FROM children, {table_name}"
    f"  WHERE {table_name}.parent_id = children.id"
    ")"
    f" SELECT {table_name}.id"
    f" FROM {table_name}, children WHERE children.id = {table_name}.id"
)
if not include_self:
    query += f" AND {table_name}.id != {self.pk}"
return Account.objects.filter(
    pk__in=[account.id for account in Account.objects.raw(query)]
)

if you use postgres , read the following link

https://www.postgresql.org/docs/current/queries-with.html#QUERIES-WITH-RECURSIVE

Back to Top