简体   繁体   English

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

[英]How to add counter column in django-tables2?

I'm trying to add a counter on the first column of a table using django-tables2, but the solution below is only showing all 0 under the # column.我正在尝试使用 django-tables2 在表的第一列上添加一个计数器,但下面的解决方案仅显示 # 列下的所有 0。 How should I add a column that will have a column that numbers the rows?我应该如何添加一列,该列将有一列对行进行编号?

tables.py:表.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')

My template:我的模板:

{% render_table table %}

Other answers all have the itertools.count instance in the toplevel scope of the tables.py file.其他答案都在tables.py文件的顶级范围内有itertools.count实例。 This makes the counter persist between page loads, it will only be reset when the server is restarted.这使得计数器在页面加载之间保持不变,它只会在服务器重新启动时重置。 A better solution is to add the counter as instance variable on the table like this:更好的解决方案是将计数器作为实例变量添加到表中,如下所示:

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)

This will make sure the counter is reset every time the table is instantiated.这将确保每次表被实例化时计数器都会被重置。

From the documentation of Column来自Column的文档

default (str or callable) : default (str or callable)

The default value for the column.列的默认值。 This can be a value or a callable object [1] .这可以是一个值或一个可调用对象[1] If an object in the data provides None for a column, the default will be used instead.如果数据中的对象为列提供None ,则将使用默认值。

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

What you are passing next(counter) you are passing the result of a function which seems to be an integer.你传递的next(counter)你传递的是一个似乎是整数的函数的结果。

You can either define a function:您可以定义一个函数:

def next_count():
    return next(counter)

and, use it as default:并且,将其用作默认值:

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

Or, you can use the lambda function as mentioned in @Sayse's comments:或者,您可以使用@Sayse 评论中提到的 lambda 函数:

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

Building on Jieter's answer, you can handle pagination with this minor modification:基于 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)

The row numbering will be globally correct even in pages after the first.即使在第一页之后的页面中,行编号也将是全局正确的。 Note that the index is 1-based in this case.请注意,在这种情况下,索引是从 1 开始的。

Adding to Jieter's answer, Inside your table class, implement these functions.添加到 Jieter 的答案中,在您的表类中,实现这些功能。 The init method is being used to get the request variable from the view class in order to fetch the page number. init方法用于从视图类获取请求变量以获取页码。 Change render_id to render_yourcolumn name.将 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)

Now in the views file, call your Table class as:现在在视图文件中,将您的 Table 类调用为:

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

By this method your counter will be correct for n number of pages.通过这种方法,您的计数器对于 n 页数来说是正确的。 :) :)

Had similar problem and didn't find any simple solution that worked on paginated tables without the counter reseting on each page有类似的问题,并没有找到任何简单的解决方案,可以在没有在每个页面上重置计数器的情况下在分页表上工作

From official FAQ: How to create a row counter?来自官方常见问题解答: 如何创建行计数器? (doesn't support pagination) (不支持分页)

Using already available paginator attributes: https://stackoverflow.com/a/9939938/3734484 (similar general django approach)使用已经可用的分页器属性: 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 }}",

    )
   ...

Here is an unprofessional way to do it, without using itertools module:这是一种不专业的方法,不使用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

from Jieter answer来自杰特回答

if do not want to start every page from zero you can do :如果不想从零开始每一页,你可以这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM