1

I have a modele to manage categories which looks like:

class Category(models.Model):
    code = models.IntegerField()
    name = models.CharField('name', max_length=200)
    slug = models.SlugField(max_length=200)
    parent = models.ForeignKey(
        "self",
        blank=True,
        null=True,
        related_name='subcategories')

Now, suppose 3 categories: cat A Cat B where parent is cat A Cat C where parent is cat B

I'd like to show a breacrumb where, for cat C, looks like to:

Home > Categories > Cat A > Cat B > Cat C

I can currently get:

Home > Categories > Cat B > Cat C

but I do not know how to get the parent of my parent. More generally, is there a way to build this breadcrumb dynamically fonction of parents ?

Thanks

smorele
  • 147
  • 12

1 Answers1

3

With your implementation (known as the 'adjacency list' pattern) you have no other choice than following your current category's parent, then it's parent's parent etc:

class Category(models.Model):
    code = models.IntegerField()
    name = models.CharField('name', max_length=200)
    slug = models.SlugField(max_length=200)
    parent = models.ForeignKey(
        "self",
        blank=True,
        null=True,
        related_name='subcategories')

   def get_parents(self):
       parents = []
       p = self.parent
       while p:
           parents.append(p)
           p = p.parent
       parents.reverse()
       return parents

Then in your template:

{% for parent in cat.get_parents %}
<a href="{{ p.get_absolute_url }}">{{ parent.label }}</a>
{% endfor %}

Now the adjacency list pattern, while being the most obvious and simplest to implement, is highly inefficient when you want to get a whole part of your hierarchy at once (like here, but also if you want all descendant of a given node etc), since it requires a lot queries.

There's a much more efficient pattern for hierarchical data modeling in SQL (much more efficient for read operations that is - it's much less efficient for write operations) known as the "nested set" pattern. It's much more complex to implement but the good news is that there's already a reusable django implementation, django-mptt, that abstracts this for you.

Unless you have hundreds of users adding / removing / reorganizing huge categeory trees all day long, I strongly suggest you switch to mptt (nested sets).

More infos on SQL and hierarchical datas here: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

and here : What are the options for storing hierarchical data in a relational database?

Community
  • 1
  • 1
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118