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