JoeFox
JoeFox

Reputation: 1081

Transpose data from model objects for django-datatables-view

I have data in the following (simplified) format:

MetricData(models.Model) with following fields: id, metric, date, facility, value

Now I want to create a table with the following format (execute the script to get the indented output table):

 <table style="width:100%">
  <tr>
    <th>Date</th>
    <th>Facility 1</th>
    <th>Facility 2</th>
    <th>Facility 3</th>
  </tr>
  <tr>
    <td>03/2019</td>
    <td>1.0</td>
    <td>1.5</td>
    <td>2.5</td>
  </tr>
  <tr>
    <td>04/2019</td>
    <td>1.5</td>
    <td>1.5</td>
    <td>2.0</td>
  </tr>
</table> 

As you can see, the number of facilities which is dynamic (new ones can be added to the database), are the column headers. For each facility there will be metric data in the database.

All examples from django-datatables-view I find are basically using models directly and one model entry is converted to one table row.

Upvotes: 2

Views: 468

Answers (1)

Lord Elrond
Lord Elrond

Reputation: 16042

You can override the QuerySet for your model to get a list of headers:

class MetricDataQuerySet(models.QuerySet):
    @property
    def headers(self):
        return [getattr(instance, self.model.header_column) for instance in self]
class MetricData(models.Model):
    header_column = 'facility'
    ...

    objects = MetricDataQuerySet.as_manager()

Notice I added the header_column, instead of hard coding facility in the QuerySet. This allows you to reuse the QuerySet for different models if you end up needing to.

Now, in your view:

def some_view(request):
    ...
    context = {
    'objects': MetricData.objects.all()
    }
    return render(request, 'some_template.html', context)

Finally, on some_template.html, you can do this:

<table>
<tr>
{% for header in objects.headers %}
  <th>{{ header }}</th>
{% endfor %}
</tr>
{% for object in objects %}
<tr>
  <td>row.date</td>
  <td>row.metric</td>
  <td>row.value</td>
</tr>
{% endfor %}
</table>

Upvotes: 1

Related Questions