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

如何在Django ModelViewSet中基于另一关联模型实现is_active过滤

完全不需要单独编写APIView,直接在现有SiteViewSet上修改即可实现/v1/site/?is_active=True的过滤需求,实现方式如下:

实现逻辑说明

AdminConfiguration中定义的is_active是Python层面的属性,无法直接用于Django ORM的数据库查询,因此需要把属性对应的判断逻辑转换为数据库可识别的查询条件,通过跨关联表的过滤即可完成需求,不需要改动原有模型,也不需要额外新增接口。

修改后的SiteViewSet代码

from django.db.models import Q
from django.utils import timezone
from rest_framework import viewsets

class SiteViewSet(viewsets.ModelViewSet):
    model = Site
    lookup_field = 'uuid'
    pagination_class = PageNumberPagination
    serializer_class = SiteSerializer
    queryset = Site.objects.all()

    def get_queryset(self):
        queryset = super().get_queryset()
        # 读取请求中的is_active查询参数
        is_active_param = self.request.query_params.get('is_active')
        if is_active_param is not None:
            # 将字符串格式的参数转为布尔值
            is_active = is_active_param.strip().lower() == 'true'
            if is_active:
                # 过滤激活状态的站点:永久激活 或 订阅未过期
                queryset = queryset.filter(
                    Q(adminconfiguration__always_active=True) |
                    Q(adminconfiguration__subscription_ends__gt=timezone.now())
                )
            else:
                # 过滤未激活状态的站点:非永久激活 且 订阅已过期
                queryset = queryset.filter(
                    Q(adminconfiguration__always_active=False) &
                    Q(adminconfiguration__subscription_ends__lte=timezone.now())
                )
        return queryset

补充说明

  • 如果存在Site未关联AdminConfiguration的场景,可以根据业务需要调整过滤条件,比如新增adminconfiguration__isnull=True的分支处理,避免查询遗漏或报错。
  • 上述修改完全兼容原ModelViewSet的所有功能,原有列表查询、详情查询、创建、更新操作不受影响,只有请求携带is_active查询参数时才会触发对应过滤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:48:06