扩展Django admin的list_filter()可使用范围方法

作者:kkevinyang 时间:2021-05-01 15:10:47 

需求描述

有时候我们会基于已有数据生成一列在表格中,类似于下面的


class BaseSchema(models.Model):
...
def test_status(self):
# pdb.set_trace()
if datetime.date.today() < self.test_start_date:
 return '未到测试区间'
elif self.test_end_date and datetime.date.today() > self.test_end_date:
 return format_html('<p style="color: red">已下线</p>')
else:
 return format_html('<p style="color: green">进行中</p>')

test_status.short_description = u'测试状态'

但同时我们也希望可以对这一列进行筛选,按常规的话也就是添加到list_filter中:


list_filter = ('test_status')

这时候我们会看到django的温馨报错:


The value of 'list_filter[0]' refers to 'test_status', which does not refer to a Field.

也就是说不能使用list_filter对非Field进行筛选。

解决办法

最简单的方法

那就是把这个字段记录进field啊,这样就可以用了。但是我并不想这么做

更高端的方法

参考https://stackoverflow.com/questions/12102697/creating-custom-filters-for-list-filter-in-django-admin/45136544#45136544第二个回答中的事例:


from django.contrib.admin import SimpleListFilter

class CountryFilter(SimpleListFilter):
title = 'country' # or use _('country') for translated title
parameter_name = 'country'

def lookups(self, request, model_admin):
countries = set([c.country for c in model_admin.model.objects.all()])
return [(c.id, c.name) for c in countries] + [
 ('AFRICA', 'AFRICA - ALL')]

def queryset(self, request, queryset):
if self.value() == 'AFRICA':
 return queryset.filter(country__continent='Africa')
if self.value():
 return queryset.filter(country__id__exact=self.value())

class CityAdmin(ModelAdmin):
list_filter = (CountryFilter,)

现在我们知道django中是这样实现的筛选的方法,那我们只要覆盖这个方法就好了:


class StatusFilter(SimpleListFilter):
title = 'status'
parameter_name = 'status'

def lookups(self, request, model_admin):
return [(1, '已下线'), (2, '进行中'), (3, '未到测试区间')]

def queryset(self, request, queryset):
this_day = datetime.date.today()
# pdb.set_trace()
if self.value() == '3':
 return queryset.filter(test_start_date__gt=this_day)
elif self.value() == '1':
 return queryset.filter(test_end_date__lt=this_day)
elif self.value() == '2':
 return queryset.filter(test_end_date__gte=this_day, test_start_date__lte=this_day)

然后在添加进list_filter中:


list_filter = (StatusFilter,)

bingo!

扩展Django admin的list_filter()可使用范围方法

来源:https://blog.csdn.net/kkevinyang/article/details/79501576

标签:Django,admin,list,filter
0
投稿

猜你喜欢

  • Vue父子组件通信全面详细介绍

    2024-06-05 09:21:16
  • Golang学习笔记(四):array、slice、map

    2024-04-30 10:02:32
  • 在ASP.NET 2.0中操作数据之二十五:大数据量时提高分页的效率

    2023-07-11 09:05:31
  • C#命名空间System.ComponentModel属性方法汇总

    2024-06-05 09:24:02
  • Tornado实现多进程/多线程的HTTP服务详解

    2023-11-19 23:40:20
  • 最新版 Windows10上安装Python 3.8.5的步骤详解

    2021-12-31 00:50:29
  • 不成熟的标准化是我们唯一惧怕的

    2008-08-15 18:55:00
  • PHP抽象工厂模式Abstract Factory Pattern优点与实现方式

    2023-05-25 03:04:57
  • 为什么MySQL不建议使用SELECT *

    2024-01-26 21:29:44
  • 用python实现面向对像的ASP程序实例

    2023-05-19 04:20:55
  • Python tempfile模块学习笔记(临时文件)

    2022-05-27 02:32:08
  • PHP如何实现HTTP验证

    2023-09-04 05:32:46
  • js实现选项卡效果

    2024-05-09 10:12:01
  • Python中IP地址处理IPy模块的方法

    2023-05-19 05:21:25
  • Python脚本实现一键自动整理办公文件

    2022-01-02 16:36:03
  • Oracle数据库完整卸载的完整步骤

    2024-01-13 13:15:30
  • golang中cache组件的使用及groupcache源码解析

    2024-02-07 11:12:25
  • 定时备份 Mysql并上传到七牛的方法

    2024-01-25 14:11:13
  • 关于Tensorflow 模型持久化详解

    2021-02-26 14:27:33
  • js不是基础的基础

    2024-05-03 15:57:54
  • asp之家 网络编程 m.aspxhome.com