Django后台列表的自定义过滤条件显示

2023-11-17 14:06:31 浏览数 (2)

前言

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

开放端口过滤器

通过开放端口筛选host记录,sport信息处于另一个模型,用到了过滤器功能。

代码语言:javascript复制
#开放端口过滤器
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 ""

0 人点赞