如何在Django Admin列表视图中添加序号(无需新增模型字段)
Django Admin列表视图添加行序号(无需新增模型字段)
你之前的代码出现序号持续累加,是因为Django的ModelAdmin是单例实例,实例变量line_numbering会在多次请求之间保留数值,导致每次刷新或翻页都会继续累加。
下面是两种简便的解决方法,都不需要新增模型字段:
方法一:基于分页计算序号(性能友好)
这种方法只针对当前页的对象计算序号,避免遍历全量数据:
from django.contrib import admin class MyModelAdmin(admin.ModelAdmin): # 把line_number加入列表显示字段 list_display = ('line_number', '你的字段1', '你的字段2') def changelist_view(self, request, extra_context=None): # 先调用父类的changelist_view获取上下文 response = super().changelist_view(request, extra_context) try: # 从上下文获取分页后的列表对象 changelist = response.context_data['cl'] # 计算当前页的起始序号 start_number = (changelist.page.number - 1) * changelist.paginator.per_page # 给当前页的每个对象添加序号属性 for index, obj in enumerate(changelist.page.object_list, start=start_number + 1): obj.row_number = index except (AttributeError, KeyError): # 异常时不处理,避免影响页面加载 pass return response def line_number(self, obj): # 返回对象的序号属性,默认0 return getattr(obj, 'row_number', 0) # 设置列表表头的显示文字 line_number.short_description = '序号'
方法二:通过查询集索引计算序号
如果你的数据量不大,也可以直接通过查询集的索引计算:
from django.contrib import admin class MyModelAdmin(admin.ModelAdmin): list_display = ('line_number', '你的字段1', '你的字段2') def changelist_view(self, request, extra_context=None): # 将当前请求保存到实例,供line_number方法使用 self.request = request return super().changelist_view(request, extra_context) def line_number(self, obj): # 获取当前的查询集(包含过滤、排序条件) queryset = self.get_queryset(self.request) # 计算当前对象在查询集中的索引,加上分页偏移量和1得到序号 page_number = self.request.GET.get('p', 1) per_page = self.list_per_page offset = (int(page_number) - 1) * per_page return offset + list(queryset).index(obj) + 1 line_number.short_description = '序号'
注意:方法二在数据量大时,list(queryset)会把整个查询集加载到内存,可能影响性能,更推荐方法一。
内容的提问来源于stack exchange,提问作者Adrian Najmrodzki
相关产品推荐
相关产品推荐

