2

I am rendering a few tables which I add to the context in the view

from .models import MyModel
from .tables import MyModelTable


def index(request):

    context = dict(all_tables=[])
    template = 'mypage/index.html'

    for x in some_list:
        if some_condition(x):
            context[x] = MyModelTable(get_some_data(x))
            context['all_tables'].append(x)

    context['all_tables'] = sort_my_way(context['all_tables'])
    return render(request, template, context)

And then I try to iterate over the list and create the tables on by one. However, I can't figure out how to get the table from the context using the string name.

index.html

{% load django_tables2 %}
{% load render_table from django_tables2 %}
<!doctype html>
<html>
    <link rel="stylesheet" href="{% static 'css/my.css' %}" />

<body>
    {% for t in all_tables %}
        {% if t %}
            <H3>{{ t }}</H3>
            {% render_table t %}  <--- How can I get the table with name t from context
            <br/>
        {% endif %}
    {% endfor %}
</body>

What I am trying to do here is saving myself from having a huge list of those here in my index.html

   {% if TABLE_1 %}
        <H3>TABLE_1 </H3>
        {% render_table TABLE_1 %}
        <br/>
    {% endif %}

    ....

   {% if TABLE_N %}
        <H3>TABLE_N </H3>
        {% render_table TABLE_N %}
        <br/>
    {% endif %}
chrise
  • 4,039
  • 3
  • 39
  • 74

2 Answers2

3

Rather than keeping the list of table names separate from the table objects in the context, it may better to keep them more closely associated to make things easier in the template.

For example, when you create the table, you could add it to the all_tables list together with its name using a tuple:

for x in some_list:
    if some_condition(x):
        named_table = (x, MyModelTable(get_some_data(x)))
        context['all_tables'].append(named_table)

You haven't shown sort_my_way() but sorting the list of tuples in context['all_tables'] will continue to work as expected with Python's sorted() and list.sort(). But you can easily customize that with a key function if you need to.

Then in your template you can loop over both the name of the table and the table itself without any extra lookup needed:

{% for name, table in all_tables %}
    {% if name %}
        <H3>{{ name }}</H3>
        {% render_table table %}
        <br/>
    {% endif %}
{% endfor %}
Will Keeling
  • 22,055
  • 4
  • 51
  • 61
1

It is not clear what the link is between x in your view and t in your template... Depending on how you built your indexes, you could try :

{% for x, t in all_tables.items %}
   ...
   {% render_table context.x %}
   ...
{% endfor %}

Or sth like that.

Arthur M
  • 69
  • 5
  • so, the x in my view gets appended to the list all_tables and at the same time is the key for that table in the context – chrise Jan 08 '19 at 08:32
  • Ok understood. You need to create a custom tag for this like `@register.filter(name='get') def get(o, index): try: return o[index] except: return ""` – Arthur M Jan 08 '19 at 08:38