Self Joining

  • 1. Note

    1. Model

    
    
                       class Category(models.Model):
                        parent = models.ForeignKey('self', related_name='subCategory', on_delete=models.CASCADE, blank = 
                        True, null=True)
                        title = models.CharField(max_length=100) 
                        slug = AutoSlugField(populate_from='title', unique=True, null=False, editable=False)
                        created_at = models.DateTimeField(auto_now_add=True)
    
                        def __str__(self):
                            return self.title
    
                        class Meta:
                            #enforcing that there can not be two categories under a parent with same slug
    
                            # __str__ method elaborated later in post.  use __unicode__ in place of
    
                            unique_together = ('slug', 'parent',)    
                            verbose_name_plural = "categories"     
    
                        def __str__(self):                           
                            full_path = [self.title]                  
                            k = self.parent
                            while k is not None:
                                full_path.append(k.title)
                                k = k.parent
                            return ' -> '.join(full_path[::-1]) 
    
                            

    2. view

    
    
                            def home(request):
                                catg = Category.objects.filter(parent=None)
                                context = {'catg':catg}    
                                return render(request, 'index.html', context)
    
                     

    3. template

    
                          {%  for i in catg %}
                                <li>{{i.title}}
                                    <ul>
                                            {%  for j in i.subCategory.all %}
                                                    <li>{{j.title}}
    
                                                            <ul>
                                                                    {%  for k in j.subCategory.all %}
                                                                        <li>{{k.title}}</li>
                                                                    {% endfor %}
                                                            </ul>
    
                                                    </li>
    
                                            {% endfor %}
    
                                    </ul>
                                </li>
                          
                          {% endfor %}