Возможно ли отобразить столбец для каждого из отношений "многие ко многим" с помощью 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
- все высоты, которые уже имеют внешний ключ для дочернего элемента.