Возможно ли отобразить столбец для каждого из отношений "многие ко многим" с помощью django-tables2?

Достаточно просто получить все отношения "многие ко многим" в определенной строке, но они отображаются в одном столбце.

Возможно ли создать столбец для каждого из них?

Например, при соотношении "многие ко многим" между Child и Year и данных для каждой пары "ребенок/год" я бы хотел, чтобы для каждого Year в таблице был столбец таблица:

Child       1998  1999  2000   
----------------------------        
Eldest       155   162   170
Youngest      53    61    72
Middlest      80    91   103

( многие ко многим в django-tables2 - это самое близкое, что я видел, к вопросу об этом, и я думаю, что принятый ответ неверен; он не отображает столбец для каждого отношения в all.)

Мне удалось найти решение.

Подход

В приведенном ниже примере у меня есть Child класс и Year объект. У меня также есть Height класс:

class Height(models.Model):
    # a Child's Height for each Year
    child = models.ForeignKey(Child)
    year = models.ForeignKey(Year)
    height = DecimalField()

Чтобы получить столбец для каждого года, содержащий рост ребенка в этом году, вы можете указать extra_columns для Table класса, определив дополнительный столбцы, которые вы хотите.

Это можно сделать с помощью get_table_kwargs() метода табличного представления.

Вам также нужен Column подкласс с render() методом, который может запрашивать базу данных, чтобы найти правильное значение для строки/столбца (осознание того, что мне нужен новый подкласс, стало для меня ключом к решению этой проблемы).

Решение

Начните с определения представления и наведения его на модель, содержащую данные:

class ChildrenTableView(tables.SingleTableView):
    model = Children

    def get_table_kwargs(self):
        year_height_columns = [
            (year.name, YearColumn(attrs={"year": year}))
            for year in Year.objects.all()
        ]
        return {"extra_columns": (year_height_columns)}

Для каждого Year нам нужен YearColumn.

attrs={"year": year} это удобный способ поместить объект Year в столбец для последующего использования в запросе. (В зависимости от ваших данных, вы также можете захотеть добавить empty_values=() к определению, чтобы столбец не думал, что он пустой.)

YearColumn это очень простой подкласс Column:

import django_tables2 as tables


class YearColumn(tables.Column):

    def render(self, record):
        return record.height_set.get(year=self.attrs["year"]).height

Здесь record - дочерний элемент для строки, а height_set - все высоты, которые уже имеют внешний ключ для дочернего элемента.

Вернуться на верх