如何在django-tables2中添加计数器列?

问题描述 投票:0回答:8

我正在尝试使用 django-tables2 在表的第一列上添加一个计数器,但下面的解决方案仅在 # 列下显示全 0。我应该如何添加一个列,该列将具有对行进行编号的列?

表.py:

import django_tables2 as tables
from profiles.models import Track
import itertools
counter = itertools.count()

class PlaylistTable(tables.Table):

    priority = tables.Column(verbose_name="#", default=next(counter))

    class Meta:
        model = Track
        attrs = {"class": "paleblue"}
        orderable = False
        fields = ('priority', 'artist', 'title')

我的模板:

{% render_table table %}
python django django-tables2
8个回答
6
投票

其他答案都在

itertools.count
文件的顶级范围内具有
tables.py
实例。这使得计数器在页面加载之间持续存在,只有在服务器重新启动时才会重置。更好的解决方案是将计数器作为实例变量添加到表中,如下所示:

import django_tables2 as tables
import itertools

class CountryTable(tables.Table):
    counter = tables.Column(empty_values=(), orderable=False)

    def render_counter(self):
        self.row_counter = getattr(self, 'row_counter', itertools.count())
        return next(self.row_counter)

这将确保每次实例化表时都会重置计数器。


3
投票

来自

Column

的文档

default (str or callable)
:

列的默认值。这可以是一个值或一个可调用对象

[1]
。如果数据中的对象为列提供
None
,则将使用默认值。

[1] - The provided callable object must not expect to receive any arguments.

您传递的内容

next(counter)
您传递的是一个函数的结果,它似乎是一个整数。

您可以定义一个函数:

def next_count():
    return next(counter)

并且将其用作默认值:

priority = tables.Column(verbose_name="#", default=next_count)

或者,您可以使用 @Sayse 评论中提到的 lambda 函数:

priority = tables.Column(verbose_name="#", default=lambda: next(counter))

3
投票

基于 Jieter 的答案,您可以通过这个小修改来处理分页:

import django_tables2 as tables
import itertools

class CountryTable(tables.Table):
    counter = tables.Column(empty_values=(), orderable=False)

    def render_counter(self):
        self.row_counter = getattr(self, 'row_counter',
                                   itertools.count(self.page.start_index()))
        return next(self.row_counter)

即使在第一页之后的页面中,行编号也将是全局正确的。请注意,在本例中索引是从 1 开始的。


0
投票

补充杰特的答案, 在表类中,实现这些函数。 init方法用于从视图类获取请求变量以获取页码。 将 render_id 更改为 render_yourcolumn 名称。

class ClassName:
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(ClassName, self).__init__(*args, **kwargs)

    def render_id(self):
        page = int(self.request.GET.get('page', 1)) - 1
        self.row_counter = getattr(self, 'row_counter', itertools.count(start=page*25+1)) # Change 25 to the number of rows in one page
        return next(self.row_counter)

现在在视图文件中,将您的 Table 类称为:

table = ClassName(ModelName.objects.values(), request=request)

通过这种方法,您的计数器对于 n 页数来说将是正确的。 :)


0
投票

有类似的问题,并且没有找到任何适用于分页表的简单解决方案,而无需在每页上重置计数器

摘自官方FAQ:如何创建行计数器?(不支持分页)

使用已有的分页器属性: https://stackoverflow.com/a/9939938/3734484(类似一般的django方法)

import django_tables2 as tables

class NumberedTable(tables.Table):
    serial_column = tables.TemplateColumn(
        verbose_name='#',
        "{{ row_counter|add:table.page.start_index }}",

    )
   ...

0
投票

这是一种不专业的方法,不使用 itertools 模块:

import django_tables2 as table

class GenericTable(table.Table):
    """GenericTable

    """
    counter = table.Column(
        verbose_name='#',
        orderable=False,
        accessor='pk',
    )

    def render_counter(self, record):
        """render_counter

        :param record: record
        :return: custom render
        """
        records = list(self.data)
        index = records.index(record)

        # counter = index  # counter starts from 0
        counter = index + 1  # counter starts from 1
        return counter

0
投票

来自杰特回答

如果不想从零开始每一页,你可以这样做:

import django_tables2 as tables
import itertools

class CountryTable(tables.Table):
    counter = tables.Column(empty_values=(), orderable=False)

    def render_counter(self):
        self.row_counter = getattr(self, 'row_counter', itertools.count())
        return next(self.row_counter)+self.page.start_index()
        # self.page.sart_index() is default Table function and return number of start index per page

0
投票

来自医生

counter = rows.TemplateColumn("{{ row_counter|add:'1' }}")

© www.soinside.com 2019 - 2024. All rights reserved.