Django - print all objects attribute values

13,519

Solution 1

With getattr, you could construct a list of list of values, like:

fields = context['fields']
context['well_info'] = [
    [getattr(o, field) for field in fields ]
    for instance in context['well_info']
]

If you write getattr(x, 'y') this is equivalent to x.y (note that for getattr(..) we use 'y' as a string, so it enables us to generate strings and query for arbitrary attributes).

For every instance in the old well_info, we thus replace it with a sublist that contains for every field, the relevant data.

Note that here the well_info attribute is no longer an iterable of model instances, but a list of lists. If you want to access both, it might be better to store it under another key in the context.

You can then render it like:

<thead>
  <tr>
    {% for field in fields %}
    <th>{{ field }}</th>
    {% endfor %}
  </tr>
</thead>
<tbody>
  {% for well in well_info %}
  <tr>
    {% for value in well %}
    <td>{{ value }}</td>
    {% endfor %}
  </tr>
  {% endfor %}
  <tr>
</tbody>

Solution 2

In your context include:

context['wellinfo'] = [(field.name, field.value_to_string(self)) for field in Well_Info._meta.fields]

Then you can loop through it in the template like:

{% for name, value in wellinfo.get_fields %}
{{ name }} {{ value }}
{% endfor %}
Share:
13,519
Eric Kim
Author by

Eric Kim

Updated on June 04, 2022

Comments

  • Eric Kim
    Eric Kim almost 2 years

    HTML

    <thead>
      <tr>
        {% for field in fields %}
        <th>{{ field }}</th>
        {% endfor %}
      </tr>
    </thead>
    <tbody>
      {% for well in well_info %}
      <tr>
        <td><p>{{ well.api }}</p></td>
        <td><p>{{ well.well_name }}</p></td>
        <td><p>{{ well.status }}</p></td>
        <td><p>{{ well.phase }}</p></td>
        <td><p>{{ well.region }}</p></td>
        <td><p>{{ well.start_date }}</p></td>
        <td><p>{{ well.last_updates }}</p></td>
      </tr>
      {% endfor %}
      <tr>
    

    views.py

    class WellList_ListView(ListView):
        template_name = 'well_list.html'
        context_object_name = 'well_info'
        model = models.WellInfo
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['fields'] = [field.name for field in models.WellInfo._meta.get_fields()]
            return context
    

    models.py

    from django.db import models
    from django.urls import reverse
    
    
    # Create your models here.
    class WellInfo(models.Model):
        api = models.CharField(max_length=100, primary_key=True)
        well_name = models.CharField(max_length=100)
        status = models.CharField(max_length=100)
        phase = models.CharField(max_length=100)
        region = models.CharField(max_length=100)
        start_date = models.CharField(max_length=100)
        last_updates = models.CharField(max_length=100)
    
        def get_absolute_url(self):
            return reverse("")
    
        def __str__(self):
            return self.well_name
    

    I was able to list all attribute field names by getting context['fields'], but I don't know how to automatically print each objects all attributes values.

    So in my html file, I hard-coded all the attribute names, but I want to know if I can to this in a more elegant way, by using for loop. So something like:

    <tbody>
      {% for well in well_info %}
      <tr>
        {% for value in attribute_list %}
        <td><p>{{ well.value }}</p></td>
        {% endfor %}
      </tr>
      {% endfor %}
      <tr>