前言
Django后台列表的自定义过滤条件显示,记录太多。只显示有用的信息。
自定义管理模型类
代码语言:javascript复制比如端口信息有很多,只显示存在线主机开放的端口信息。
# Register your models here.
class SPortAdmin(admin.ModelAdmin):
#后台展示字段
list_display = ['id','name', 'port', 'protocol', 'show_host_num', 'is_scanned']
#排序
ordering = ['id']
#过滤字段
list_filter = ['protocol', 'is_scanned']
#搜索字段
search_fields = ['port']
# 定义一些操作示例
@admin.display(description='主机数', ordering='id')
def show_host_num(self, obj):
host_count = Host.objects.filter(open_ports__in=[obj]).annotate(num_hosts=Count('id')).values('num_hosts')
if host_count:
return host_count[0]['num_hosts']
else:
return 0
# 过滤, 只打印存在开放主机的端口列表
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(num_hosts=Count('s_port')).filter(num_hosts__gt=0) # 过滤出 num_hosts 大于 0 的记录
return queryset
开放端口过滤器
代码语言:javascript复制通过开放端口筛选host记录,sport信息处于另一个模型,用到了过滤器功能。
#开放端口过滤器
class OpenPortsFilter(admin.SimpleListFilter):
title = 'Open Ports'
parameter_name = 'open_ports'
def lookups(self, request, model_admin):
open_ports = set(Host.objects.values_list('open_ports__port', flat=True).distinct())
return ((port, port) for port in open_ports if port)
def queryset(self, request, queryset):
if self.value():
return queryset.filter(open_ports__port=self.value())
class HostAdmin(admin.ModelAdmin):
#后台展示字段
list_display = ['id', 'ip_address', 'status', 'project', 'is_monitor', 'operate']
#过滤字段
list_filter = ['project', OpenPortsFilter]
#搜索字段
search_fields = ['ip_address']
#自定义动作
actions = ['host_open_port_scan']
# 定义一些操作示例
@admin.display(description='操作', ordering='id')
def operate(self, obj):
if obj.open_ports.count() > 0:
#端口列表
paras = {'name':'开放端口', 'icon': 'fas fa-user-tie', 'url':'/monitor/listports/?hid={}'.format(obj.id)}
portlist_btn = "端口列表"
html_str = "" portlist_btn ""
return format_html(html_str, a_a=paras)
else:
return ""