How to Dynamically Populate a Table in an Included Template Using Blocks?

Hi everyone,

I’m working on a Django project where I want to include a generic table layout in a shared partial template and populate its rows dynamically from different views/templates. I’m trying to use Django’s {% block %} and {% include %} mechanisms, but the content isn’t rendering as expected.

Note: This question uses generic file names, structures, and variable names. I’m not sharing real project data.

My project is basically structured that way:

myproject/
├── myapp/
│   ├── templates/
│   │   └── consultoria/
│   │       └── my_template.html
├── global/
│   ├── templates/
│   │   └── global/
│   │       ├── base.html
│   │       └── partials/
│   │           └── _table.html

I tryed to structure a reusable table in _table.html (inside global/partials/) like this:

<!-- global/templates/global/partials/_table.html -->
<div class="responsive-table">
    <table class="user-table">
        <thead>
            <tr>
                <th>Column 1</th>
                <th>Column 2</th>
                <th>Column 3</th>
            </tr>
        </thead>
        <tbody>
            {% block tbody_block %}
            {% endblock %}
        </tbody>
    </table>
</div>

In my actual page template (my_template.html), I try to do:

{% extends "global/base.html" %}

{% block content %}
    {% include 'global/partials/_table.html' %}
{% endblock content %}

{% block tbody_block %}
    {% for item in table_items %}
    <tr>
        <td>{{ item.field1 }}</td>
        <td>{{ item.field2 }}</td>
        <td>{{ item.field3 }}</td>
    </tr>
    {% endfor %}
{% endblock tbody_block %}

The table renders, but the tbody_block override doesn’t appear.

Is it possible to override a {% block %} inside an {% include %} the way I’m attempting?
If not, what’s the recommended way to reuse a generic table structure and inject dynamic row content?

Thanks in advance!

As you have seen, no. Blocks don’t work that way. (In particular, see the “Note” block in the docs for the include tag.

In short, the quick answer is that you either don’t include that block in the partial - you make it part of the my_template, or create a template that extends my_template that includes the partial and the supplemental data as separate blocks.

Unfortunately, this is one of those situations where trying to discuss this abstractly tends to lead to more problems or confusion. This is one of those cases where it’s really better to talk about this in the specific context of your existing project. Why? Because a proper solution should be looked at in the context of the site as a whole, not as a “point solution” for this specific case. Yes, I’m making an assumption that this isn’t the only instance of this type of situation in your project, and a more comprehensive answer would requre more complete information about the other templates possibly affected by this.

The best answer is only going to come from understanding all your site requirements and looking at all the page structures needing templates.

1 Like

Hi! Thank you for your previous response — I now understand that {% block %} tags won’t work inside an {% include %}, as I initially hoped.

I’m building a web application that involves CRUD operations over different object types (e.g., “Assets”, “Priced Assets”, etc.). I want to reuse a base HTML table structure, and inject different row contents depending on the object type.

Each table has:

  • A shared structure: <thead> and general layout (caption, header class, table responsiveness)
  • A varying <tbody>: Different objects have different fields (e.g., some with price, others with checkboxes, and others with action buttons)



Since my project includes multiple table with variations variations — for example, some include price fields, others add checkboxes or action buttons (as shown above) — I was wondering if it is considering redundant to creating a full, separate template for each variation if it’s not necessary.

Or if there is a better way to reuse the base table structure while dynamically customizing just the body rows (or a few columns) per view.

Yes, this.

The key is to make your templates flexible, and construct your context to take advantage of that.

Keep in mind that the include tag can take a variable as a parameter, allowing different templates to be included. Also, there’s a lot that can be done by assigning segments to common names regardless of the data.

Think of this as being similar to how forms work. When you render a form, you’re rendering some number of different widgets - one per field. Within that field, you’re rendering some different mix of data.

If you get to the point where you’re understanding how forms render, that should give you some ideas as to how you can construct your templates for maximum flexibility.

1 Like

Thank you for the clarification!

@KenWhitesell, hi!

Based on your previous explanation, I’ve been working on making my templates more flexible by separating out the base table structure and dynamically including specific parts.

One idea I had was to create a base template called table.html like this:

{% extends "global/base.html" %}
{% block content %}
<div class="responsive-table">
    <div class="search table-search">
        <form action="" method="get">
            <input type="text" class="search-input" placeholder="Search" id="search" name="q" value="{{ request.GET.q }}">
        </form>
    </div>     
    <table class="user-table">
        <thead>
            <tr class="table-row table-row-header">
                {% for user_header in table_user_headers %}
                    <th class="table-header">{{ user_header }}</th>
                {% endfor %}
            </tr>
        </thead>
        <tbody>
            {% include template_name %}
        </tbody>
    </table>
</div>
{% endblock %}
  • base.html is the common base for all pages. Inside it there is a {%block content%}{% endblock %} to be filled.
  • template_name is the name of the template that contains the specific table body.
  • table_user_headers is passed through each view according to the table.

However, I’m still running into some duplication. For example, I have tarefa.html and ativo.html with very similar structures:

tarefa.html:

{% for obj in model_objs %}
    <tr class="table-row">
        <td class="table-cel">{{ obj.topico }}</td>
        <td class="table-cel">{{ obj.descricaoCompleta }}</td>
    </tr>
{% endfor %}

ativo.html:

{% for obj in model_objs %}
    <tr class="table-row">
        <td class="table-cel">{{ obj.Id }}</td>
        <td class="table-cel">{{ obj.nome }}</td>
    </tr>
{% endfor %}

To avoid this duplication, I thought about adding a method getValues() to each model, like this:

def getValues(self):
    return [self.topico, self.descricaoCompleta]

Then, in the template, I could render it generically like this:

{% for obj in model_objs %}
    <tr class="table-row">
        {% for value in obj.getValues %}
            <td class="table-cel">{{ value }}</td>
        {% endfor %}
    </tr>
{% endfor %}

Does this seem like a reasonable approach?

That is a very reasonable approach. This will also work for models with more than two fields.