How to display categories and subcategories that belong to their categories in django?

My scenario:

I'm having three tables,

  • Category
  • Subcategory
  • Products

While inserting new product, there are two select boxes

  • 1st select is for Category (its working)

  • 2nd is for Subcategory, which should be relevant to the 1st select. Needs to show subcategory table inside bets categories. (it doesn't work properly)

Subcategory table has category id as a foreign key. I am a beginner, please somebody help.

My models.py

from django.db import models
from django.urls import reverse


class Category(models.Model):
    cat_name = models.CharField(max_length=25, verbose_name='Categ', db_index=True)
    cat_slug = models.SlugField(max_length=255, unique=True, db_index=True, verbose_name="SLUG")

    def __str__(self):
        return self.cat_name

    def get_absolute_url(self):
        return reverse('category', kwargs={'cat_slug': self.cat_slug})

    class Meta:
        ordering = ['cat_name']


class SubCategory(models.Model):
    category = models.ForeignKey('Category', on_delete=models.SET_NULL, related_name='category', null=True, blank=True, db_index=True,
                                      verbose_name='Categ')
    scat_name = models.CharField(max_length=25, unique=True, db_index=True, verbose_name='Name')
    scat_slug = models.SlugField(max_length=255, unique=True, db_index=True, verbose_name="SLUG")

    def __str__(self):
        return self.scat_name

    def get_absolute_url(self):
        return reverse('subcategory', kwargs={'scat_slug': self.scat_slug})

    class Meta:
        ordering = ['scat_name']


class Product(models.Model):
    price = models.IntegerField(default=0, verbose_name="Price")
    category = models.ForeignKey('Category', on_delete=models.SET_NULL, related_name='products', null=True, verbose_name="Categ")
    subcategory = models.ForeignKey('SubCategory', on_delete=models.SET_NULL, related_name='products', null=True, verbose_name="SubCateg")
    title = models.CharField(max_length=255, db_index=True, verbose_name="Title")
    slug = models.SlugField(max_length=255, unique=True, db_index=True, verbose_name="URL")
    content = models.TextField(blank=True, verbose_name="Text")
    photo = models.ImageField(upload_to="images/%Y/%m/%d/", verbose_name="Photo")
    time_create = models.DateTimeField(auto_now_add=True, verbose_name="Created")
    time_update = models.DateTimeField(auto_now=True, verbose_name="Updated")
    is_published = models.BooleanField(default=True, verbose_name="Published")

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('product', kwargs={'prod_slug': self.slug})

    class Meta:
        ordering = ['id']

My views.py

from django.http import HttpResponse, HttpResponseNotFound
from django.shortcuts import render
import json
from .models import *

menu = [
    {'title': "Home", 'url_name': 'home'},
    {'title': "Contact", 'url_name': 'contact'},
    {'title': "Login", 'url_name': 'login'},
]


def index(request):
    products = Product.objects.all()
    categories = Category.objects.all()
    subcategories = SubCategory.objects.all()
    context = {'products': products,
               'subcategories': subcategories,
               'categories': categories,
               'menu': menu,
               'title': 'Home',
               }
    return render(request, 'main/index.html', context)

My index.html (each category shows all subcategories, even those that do not belong to them.)

{% extends 'main/base.html' %}

{% block content %}
<h1>{{title}}</h1>
{{mainmenu}}


{% for c in categories %}
<ul>
<li><a href="{{ cat.get_absolute_url }}">{{c.cat_name}}</a></li>
    {% for sc in subcategories %}
        <li><a href="{{ scat.get_absolute_url }}">{{sc.scat_name}}</a></li>
    {% endfor %}
</ul>
{% endfor %}

<ul class="list-articles">
    {% for prod in products %}
    <li>
        <div class="article-panel">
            <h2>{{prod.title}}</h2>
            <p class="first">Category: {{prod.category}}  {{prod.subcategory}}</p>
            <p class="last">Date: {{prod.time_update|date:"d-m-Y H:i:s"}}</p>

        </div>
    </li>
    {% if prod.photo %}
    <p><img class="img-article-left thumb" src="{{prod.photo.url}}"></p>
    {% endif %}
    <li><p>{{prod.content}}</p>
        {% autoescape on %}
        {{p.content|linebreaks|truncatewords:50}}
        {% endautoescape %}
        <div class="clear"></div>
        <p><a href="{% url 'product' prod.slug %}">More...</a></p>
    </li>
    {% endfor %}
</ul>



{% endblock %}

Please help me. I can't figure out where I did something wrong.

Back to Top