You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中跨3个模型聚合数据并渲染至HTML模板

Django 按主机分组汇总漏洞数据的解决方案

先确认模型关联(按需调整字段)

假设你的模型结构如下,确保ClientVULDB的外键关联正确设置related_name:

class ClientDB(models.Model):
    hostname = models.CharField(max_length=100, unique=True)
    # 其他主机字段(如IP、操作系统等)

class VULDB(models.Model):
    title = models.CharField(max_length=200)
    # 其他漏洞字段(如CVE编号、风险等级等)

class ClientVULDB(models.Model):
    client = models.ForeignKey(ClientDB, on_delete=models.CASCADE, related_name='vul_relations')
    vul = models.ForeignKey(VULDB, on_delete=models.CASCADE)
    # 可选字段:扫描时间、修复状态等

视图实现方案

方案1:用Django聚合函数(推荐,适合PostgreSQL)

利用StringAgg直接在数据库层面完成分组聚合,效率更高:

from django.db.models import StringAgg
from django.shortcuts import render
from .models import ClientDB

def host_vul_summary(request):
    # 按主机分组,聚合去重后的漏洞标题,用顿号分隔
    host_vuls = ClientDB.objects.annotate(
        vul_titles=StringAgg('vul_relations__vul__title', delimiter='、', distinct=True)
    ).all()
    return render(request, 'vul_summary.html', {'host_vuls': host_vuls})

注:如果用MySQL,需要安装django-mysql包,替换StringAgg为GroupConcat

方案2:手动分组(兼容所有数据库,更灵活)

通过遍历主机,逐个获取关联漏洞,适合需要额外处理逻辑的场景:

from django.shortcuts import render
from .models import ClientDB

def host_vul_summary(request):
    host_vul_list = []
    for client in ClientDB.objects.all():
        # 获取该主机关联的所有去重漏洞标题
        vul_titles = client.vul_relations.values_list('vul__title', flat=True).distinct()
        host_vul_list.append({
            'hostname': client.hostname,
            'vul_titles': vul_titles
        })
    return render(request, 'vul_summary.html', {'host_vul_list': host_vul_list})

模板渲染

根据选择的视图方案,对应编写HTML模板:

对应方案1的模板:

{% for host in host_vuls %}
    <div>
        <strong>{{ host.hostname }}</strong> 对应 {{ host.vul_titles|default:"无漏洞" }}
    </div>
{% endfor %}

对应方案2的模板:

{% for item in host_vul_list %}
    <div>
        <strong>{{ item.hostname }}</strong> 对应 
        {% for title in item.vul_titles %}
            {{ title }}{% if not forloop.last %}、{% endif %}
        {% empty %}
            无漏洞
        {% endfor %}
    </div>
{% endfor %}

关键注意事项

  • 确保ClientVULDB的client字段设置了related_name='vul_relations',否则无法通过主机对象直接关联漏洞关系
  • 使用distinct()避免同一主机重复显示相同漏洞标题
  • 如果需要按漏洞风险等级过滤,可在查询集里添加filter(vul_relations__vul__severity='高危')这类条件

内容的提问来源于stack exchange,提问作者xMonkey1337

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 00:12:54