0

I'm building a template to render several models in the same table format. I use a class based listviews to access the model.

I've also overwritten the context to give the fields needed for each type of model :

views.py

class ProductListView(ListView):
    template_name = 'myApp/table.html'
    model = Product

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['fields'] = ['name', 'product_type', 'cost', 'margin']
        return context

In the template, I'd like to loop through the given fields, by doing :

        {% for element in object_list %}
        <tr>
            {% for field in fields %}
            <td>{{ element.field }}</td>
            {% endfor %}
        </tr>
        {% endfor %}

But it does not display anything. I've read in the documentation (https://docs.djangoproject.com/en/3.1/ref/templates/language/) that :

Note that “bar” in a template expression like {{ foo.bar }} will be interpreted as a literal string and not using the value of the variable “bar”, if one exists in the template context.

and I understand what I'm doing wrong but I can't figure out how to display this field. I can't just explicitely write the field names in the template because I want this template to be able to handle differents models.

Is there any way to loop through the given fields ?

LucBed
  • 1
  • 4
  • Does this answer your question? [Iterate over model instance field names and values in template](https://stackoverflow.com/questions/2170228/iterate-over-model-instance-field-names-and-values-in-template) – xyres Jan 15 '21 at 15:41
  • Not really : I read it during my research but it's about only one object. I can't figure out how to apply this to a list of elements. – LucBed Jan 15 '21 at 15:57

2 Answers2

0

I just found a solution. I think it is not very clean but it works :

views.py

class ProductListView(TemplateView):
    template_name = 'myApp/table.html'

    def get_context_data(self, *args, **kwargs):
        context = super(ProductListView, self).get_context_data(*args, **kwargs)
        fields = ['name', 'product_type', 'cost', 'margin']
        query_set = Product.objects.all()
        context['element_list'] = [[getattr(obj, field) for field in fields] for obj in query_set]
        return context

table.html

        {% for element in element_list %}
        <tr>
            {% for field in element %}
            <td>{{ field }}</td>
            {% endfor %}
        </tr>
        {% endfor %}

It is not using ListView as I planned but it does the job !

LucBed
  • 1
  • 4
0

may be, like this:

views.py

class ProductListView(ListView):
    template_name = 'myApp/table.html'
    context_object_name = 'products'

    def get_queryset(self):
        return Product.objects.all()

table.html

        {% for product in products %}
        <tr>
            <td>product.name</td>
            <td>product.product_type</td>
            <td>product.cost</td>
            <td>product.margin</td>
        </tr>
        {% endfor %}
OlegТ
  • 173
  • 9
  • It works indeed for this specific case but I want my template to be as generic as possible, and to be able de work for any model given by a ListView – LucBed Jan 15 '21 at 16:41
  • Simple is better than complex. Complex is better than complicated. ;-) – OlegТ Jan 15 '21 at 17:03