How can I display a table in a template with additional category/section rows?

Have a nice day!

I have a non-standard table. Which I plan to display in the template.

I load the table into the template from the model. And I have additional sections - additional fields. These additional fields characterize - Category, Section, Topics. I am thinking how to display such a table from the model in the template - as shown in the picture.

To additionally implement additional fields - categories or sections in the table.

I have a rough idea -

I have to create a transit model for exactly such a table - in which the number of rows is equal to the number of rows of the original table + plus the number of rows of category sections in addition. That is, there can be about 25 rows of the original table and + plus 6 rows - category sections. In total, the required table will have 31 rows of rows.

enter image description here

But how to display them in the form as in my picture - separating categories sections?

models.py

class CreateNewGPR (models.Model):
    name_object = models.IntegerField(verbose_name="")
    name_category = models.CharField(verbose_name="")
    name_working = models.CharField(verbose_name="")
    type_izm = models.CharField(choices=TYPE_IZMERENIYA, verbose_name="")
    value_work = models.FloatField(verbose_name="")
    lyudi_norma = models.IntegerField(verbose_name="")
    technik_norma = models.IntegerField(verbose_name="")
    date_begin = models.DateField(verbose_name="")
    date_end = models.DateField(verbose_name="")

views.py

filter_qs = CreateNewGPR.objects.filter(name_object=pk) filter_qs = filter_qs.values("name_working", "type_izm", "value_work", "lyudi_norma", "technik_norma", "date_begin", "date_end")

context['books'] = filter_qs

template.html

<div>
        <table class="pure-table">
            <thead>
                <tr>
                    <th>Name Column 1</th>
                    <th>Name Column 2</th>
                    <th>Name Column 3</th>
                    <th>Name Column 4</th>
                    <th>Name Column 5</th>
                    <th>Name Column 6</th>
                    <th>Name Column 7</th>
                </tr>
            </thead>
            <tbody>
                {% for book in books %}
                <tr>
                    <td>{{ book.name_working }}</td>
                    <td>{{ book.type_izm }}</td>
                    <td>{{ book.value_work }}</td>
                    <td>{{ book.lyudi_norma }}</td>
                    <td>{{ book.technik_norma }}</td>
                    <td>{{ book.date_begin }}</td>
                    <td>{{ book.date_end }}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>

Just associate it in your code if you are sure that there will always only one page with few objects:

def get_context_data(self, **kwargs) -> dict[str, typing.Any]:
    context = super().get_context_data()
    categories = collections.defaultdict(list)
    for object in self.get_queryset():
        categories[object.category].append(object)
    context["categories"] = categories
    return context

And then render it in template (here is example of html, fill it in template by yourself):

<table>
  <thead>
    <tr>
      <th>col1</th>
      <th>col2</th>
      <th>col3</th>
    </tr>
  </thead>
  
  <tbody>
    <tr>
      <th colspan="3">category 1</th>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    
    <tr>
      <th colspan="3">category 2</th>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>2</td>
    </tr>
  </tbody>
</table>

🧩 1. Update views.py to group data by category

python

CopyEdit

from collections import defaultdict

def your_view(request, pk):
    # Get all objects for a specific `name_object`
    filter_qs = CreateNewGPR.objects.filter(name_object=pk)

    # Group by category
    grouped_data = defaultdict(list)
    for item in filter_qs:
        grouped_data[item.name_category].append(item)

    context = {
        'grouped_data': grouped_data.items()  # returns list of (category, items)
    }
    return render(request, 'your_template.html', context)

🖼️ 2. Update your template.html to display grouped sections

html

CopyEdit

<table class="pure-table">
    <thead>
        <tr>
            <th>Name Working</th>
            <th>Type</th>
            <th>Value</th>
            <th>Lyudi Norma</th>
            <th>Technik Norma</th>
            <th>Start Date</th>
            <th>End Date</th>
        </tr>
    </thead>
    <tbody>
        {% for category, items in grouped_data %}
            <!-- Category Row -->
            <tr style="background-color:#f0f0f0; font-weight:bold;">
                <td colspan="7">Category: {{ category }}</td>
            </tr>

            {% for item in items %}
            <tr>
                <td>{{ item.name_working }}</td>
                <td>{{ item.type_izm }}</td>
                <td>{{ item.value_work }}</td>
                <td>{{ item.lyudi_norma }}</td>
                <td>{{ item.technik_norma }}</td>
                <td>{{ item.date_begin }}</td>
                <td>{{ item.date_end }}</td>
            </tr>
            {% endfor %}
        {% endfor %}
    </tbody>
</table>

This will render your table grouped by name_category, with clear section headers inserted dynamically — no need to manually create a “transit” model or add extra rows.
🔁 Bonus: Sorting by name_category

If you want sections to appear in a specific order:
filter_qs = CreateNewGPR.objects.filter(name_object=pk).order_by('name_category', 'name_working')

Вернуться на верх