django-tables2 css 用于分组行
django-tables2 css for grouped rows
使用 django-tables2 非常愉快。我现在正试图弄清楚如何根据行内容更改行的 css 。例如,给定 table:
header 1 | header 2
---------|---------
value 1 | 1
value 2 | 1
value 3 | 2
value 4 | 2
value 5 | 2
value 6 | 3
value 7 | 3
我希望能够为具有相同 'header 2' 值和相同 class 的连续行设置样式。使用 itertools.groupby,可以很容易地对应该分组的值进行分组,但我无法弄清楚如何遍历 table 对象并更新每一行的 class 属性。
对于列,可以动态更新属性。例如,在 init, self.columns['ColumnName'].column.attrs = {'td': {'class': 'foo'}} 作品。
但是,对于行,这个(和各种排列)不起作用:
for i in self.rows:
i.attrs = {'tr': {'class': 'foo'}} # *** AttributeError, can't set attribute
i.cells.row.attrs = {...} # *** AttributeError
i.cells.row.attrs['class'] = 'foo' # Seems to work, but attrs not updated
# same as above
i.cells.row.attrs.update({'tr': {'class': 'foo'}})
i.table.row_attrs = {'class': 'foo'} # works, but applies to the whole table at once.
很明显,我的做法是错误的。该文档建议在 class Meta 中使用 row_attrs 并且它可以具有 return class 值的功能。但是,在该函数中,一次只能看到一行(作为 'record' 对象传递),而在这种情况下,需要将 table 作为一个整体进行解析,因此 init 似乎是解决这个问题的更好地方。
对于这种棘手情况的解决方案或任何指示,我们将不胜感激。
如果您想访问前面的行,您可以使用可调用函数返回一个可调用函数,如下所示:
def group_by_heading():
class_names = ["red", "blue", "yellow", ...]
previous = None
def inner(record):
# in first row and after every change, remove the first element
# and use it as the current class name.
if previous is None or record.header_2 != previous.header_2:
class_name = class_names.pop(0)
previous = record
return class_name
return inner
class Table(tables.Table):
class Meta:
row_attrs = {'td': {'class': group_by_heading()}}
注意函数 group_by_heading
在添加到 row_attrs
字典时被 调用 。这叫做 closure
请注意,这不是一个完整的示例。如果按原样应用,class_names 的列表将很快 exhausted
因为每次呈现 table 时都会重新使用它。
您可以通过将 row_attrs
添加到视图中的 table 来解决此问题。例如,使用 SingleTableView
:
class MyView(tables.SingleTableView):
table_class = MyTable
queryset = Model.objects.all()
def get_table_kwargs(self):
return {"row_attrs": {'td': {'class': group_by_heading()}}}
这将确保每个 table 视图都使用新的 class_names 列表。
使用 django-tables2 非常愉快。我现在正试图弄清楚如何根据行内容更改行的 css 。例如,给定 table:
header 1 | header 2
---------|---------
value 1 | 1
value 2 | 1
value 3 | 2
value 4 | 2
value 5 | 2
value 6 | 3
value 7 | 3
我希望能够为具有相同 'header 2' 值和相同 class 的连续行设置样式。使用 itertools.groupby,可以很容易地对应该分组的值进行分组,但我无法弄清楚如何遍历 table 对象并更新每一行的 class 属性。
对于列,可以动态更新属性。例如,在 init, self.columns['ColumnName'].column.attrs = {'td': {'class': 'foo'}} 作品。 但是,对于行,这个(和各种排列)不起作用:
for i in self.rows:
i.attrs = {'tr': {'class': 'foo'}} # *** AttributeError, can't set attribute
i.cells.row.attrs = {...} # *** AttributeError
i.cells.row.attrs['class'] = 'foo' # Seems to work, but attrs not updated
# same as above
i.cells.row.attrs.update({'tr': {'class': 'foo'}})
i.table.row_attrs = {'class': 'foo'} # works, but applies to the whole table at once.
很明显,我的做法是错误的。该文档建议在 class Meta 中使用 row_attrs 并且它可以具有 return class 值的功能。但是,在该函数中,一次只能看到一行(作为 'record' 对象传递),而在这种情况下,需要将 table 作为一个整体进行解析,因此 init 似乎是解决这个问题的更好地方。
对于这种棘手情况的解决方案或任何指示,我们将不胜感激。
如果您想访问前面的行,您可以使用可调用函数返回一个可调用函数,如下所示:
def group_by_heading():
class_names = ["red", "blue", "yellow", ...]
previous = None
def inner(record):
# in first row and after every change, remove the first element
# and use it as the current class name.
if previous is None or record.header_2 != previous.header_2:
class_name = class_names.pop(0)
previous = record
return class_name
return inner
class Table(tables.Table):
class Meta:
row_attrs = {'td': {'class': group_by_heading()}}
注意函数 group_by_heading
在添加到 row_attrs
字典时被 调用 。这叫做 closure
请注意,这不是一个完整的示例。如果按原样应用,class_names 的列表将很快 exhausted
因为每次呈现 table 时都会重新使用它。
您可以通过将 row_attrs
添加到视图中的 table 来解决此问题。例如,使用 SingleTableView
:
class MyView(tables.SingleTableView):
table_class = MyTable
queryset = Model.objects.all()
def get_table_kwargs(self):
return {"row_attrs": {'td': {'class': group_by_heading()}}}
这将确保每个 table 视图都使用新的 class_names 列表。