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

在Django Rest Framework中如何过滤含关联数组条件的服务器列表

实现IPv4 VLAN组名称过滤PhysicalServer列表

首先,我们需要通过嵌套关联查询来过滤出包含指定VLAN组名称的IPv4的服务器,同时要注意避免重复结果和优化查询性能。以下是具体的改造步骤:

1. 修改get_queryset方法,添加过滤逻辑

在你的PhysicalServerListAPIView的get_queryset方法中,新增VLAN组名称的参数处理和过滤条件:

def get_queryset(self):
    query_params = self.request.query_params
    id_list = get_param_from_query_params(query_params, 'id_list[]', True)
    sort_param = get_param_from_query_params(query_params, 'sort_param')
    ip = get_param_from_query_params(query_params, 'ip')
    server_status = get_param_from_query_params(query_params, 'server_status')
    # 新增:获取VLAN组名称过滤参数
    vlan_group_name = get_param_from_query_params(query_params, 'vlanedipv4networkgroup_name')
    ...
    
    # 生成filters时排除VLAN组参数,避免错误的contains过滤
    filters = {
        '{}__contains'.format(key): value 
        for key, value in query_params.items() 
        if value is not None 
        and key not in ["page", "page_size", "vlanedipv4networkgroup_name"]
    }
    qs = PhysicalServer.objects.filter(user=self.request.user).filter(**filters)
    
    if id_list:
        qs = qs.filter(id__in=id_list)
    if ip:
        qs = qs.filter(ipv4s__ip=ip).prefetch_related(
            Prefetch('ipv4s', queryset=IPv4Manage.objects.filter(ip=ip)))
    # 新增:处理VLAN组名称过滤
    if vlan_group_name:
        # 过滤出至少有一个IPv4属于指定VLAN组的服务器
        qs = qs.filter(ipv4s__vlaned_ipv4network__name=vlan_group_name).distinct()
        # 可选:预取符合条件的IPv4条目,减少数据库查询并优化返回结果
        qs = qs.prefetch_related(
            Prefetch('ipv4s', queryset=IPv4Manage.objects.filter(vlaned_ipv4network__name=vlan_group_name))
        )
    if bandwidth:
        qs = qs.filter(Q(switchesport__bandwidth=bandwidth))
    # 排序逻辑
    qs = qs.annotate(letters=Substr('name', 1, 6), length=Length('name'))
    return qs.order_by('pay_time', 'letters', 'length', 'name')

2. 关键细节说明

  • 嵌套关联查询:ipv4s__vlaned_ipv4network__name是Django的关联查询语法,依次关联PhysicalServer→IPv4Manage→VlanedIPv4Network的name字段。注意这里用的是模型里的字段名vlaned_ipv4network,对应你API返回中的vlanedipv4networkgroup应该是序列化时的字段重命名,确保关联关系正确即可。
  • distinct()去重:一个服务器可能有多个符合条件的IPv4条目,直接过滤会返回重复的服务器对象,distinct()可以保证每个服务器只出现一次。
  • 可选的Prefetch优化:如果希望API返回的ipv4s数组只包含符合VLAN组条件的条目,就保留Prefetch代码;如果需要返回服务器的所有IPv4(仅过滤服务器本身),可以去掉这部分。

3. 请求使用示例

现在你可以通过以下请求来过滤目标服务器:

GET localhost:8000/api/server/list?vlanedipv4networkgroup_name=52

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:50:47