Search code examples
pythondjangohtml-tabledjango-templatesdjango-tables2

can i make a two dimensional table in django-tables2?


Edited: Hi guys, I have been looking for a solution to my problem for some days without an answer I am trying to make a two-dimensional table with data obtained from the same model. The idea is to list the students in rows, the data in columns and the status in their respective cells, a two dimensional table.

class DailyAttendanceStudent(models.Model):
    ATTENDANCE_CHOICES = (
        (None,''),
        (True,'Presente'),
        (False, 'Ausente')
        )
    date = models.DateField(default=datetime.datetime.now)
    status = models.NullBooleanField(choices=ATTENDANCE_CHOICES)
    student = models.ForeignKey('perfiles.Student')

These are my table:

class StudentAttendanceTable(tables.Table):
    nombres = tables.Column('nombres', accessor='Student.first_name')
    apellidos = tables.Column('apellidos', accessor='Student.last_name')
    date = tables.Column('fecha', accessor='date')#LinkColumn
    status = tables.Column('status', accessor='status')
    class Meta:
        model = DailyAttendanceStudent
        fields = ('nombres', 'apellidos', 'date', 'status')

graphically this is what I want to do:

I want to do this


Solution

  • I think I would do something like this:

    • Filter the DailyAttendanceStudent queryset like desired, and pass it to your table.
    • Implement a custom constructor for your table, doing something like this:
      • Loop over the queryset, transforming it to a OrderedDict with the user id as key. For any new date you should add a new column to the instance, and add a key for that date to the OrderedDict.
      • The new column can be a table.Column, or something specialized to suit your needs.
      • The custom constructor should call the constructor of the parent class, passing the items of the OrderedDict as data and the date columns as extra_columns.

    In code, it could look like this:

    from collections import OrderedDict
    import django_tables2 as tables
    
    class StudentAttendanceTable(tables.Table):
        nombres = tables.Column('nombres', accessor='student.first_name')
        apellidos = tables.Column('apellidos', accessor='student.last_name')
    
        def __init__(self, data, *args, **kwargs):
            rows = OrderedDict()
            extra_columns = {}
            for row in data:
                if row.student.id not in rows:
                    rows[row.student.id] = {'student': row.student}
                rows[row.student.id][row.date] = row.status
                extra_columns[row.date.isoformat()] = tables.Column()  # use more specialized column if you get this to work
            super(StudentAttendanceTable, self).__init__(data=rows.values(), extra_columns=extra_columns.items(), *args, **kwargs)
    

    You might want to sort the value you pass to extra_columns, as the order retrieved from the database might not be the desired order for presentation.