Django 3关联对象场景自定义管理器失效问题解决方案咨询
Django 3+ 关联对象软删除管理器实现方案
不需要逐个修改序列化器新增过滤条件,原生Django提供了可全局生效的实现方案,以下是两种常用落地方式:
- 方案1:配置模型全局管理器(优先推荐)
Django 3.2+ 支持通过模型Meta的base_manager_name参数指定全局基础管理器,关联查询会默认调用该管理器的过滤逻辑,示例代码如下:
from django.db import models # 自定义软删除管理器 class SoftDeleteManager(models.Manager): def get_queryset(self): # 全局过滤已软删除的数据 return super().get_queryset().filter(deleted=False) class YourBusinessModel(models.Model): deleted = models.BooleanField(default=False, verbose_name="软删除标识") # 其他业务字段省略 # 自定义管理器作为默认管理器 objects = SoftDeleteManager() # 保留原生管理器用于需要查询全量数据的场景(如后台任务、数据统计) all_objects = models.Manager() class Meta: # 指定默认管理器 default_manager_name = "objects" # 指定基础管理器,关联查询会自动调用该管理器 base_manager_name = "objects"
配置完成后,所有关联YourBusinessModel的查询都会自动过滤deleted=True的软删除数据,无需修改序列化器或业务查询代码。
- 方案2:自定义关联字段管理器(适合精细控制场景)
如果仅需要部分关联关系走软删除过滤,可单独给指定关联字段替换管理器,示例代码如下:
from django.db import models # 自定义反向关联管理器生成方法 def create_soft_delete_related_manager(super_class): class SoftDeleteRelatedManager(super_class): def get_queryset(self): return super().get_queryset().filter(deleted=False) return SoftDeleteRelatedManager # 业务模型定义 class Order(models.Model): # 订单主表 pass class OrderItem(models.Model): order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="items") deleted = models.BooleanField(default=False) # 其他订单项字段省略 # 给Order的items反向关联单独替换软删除管理器 Order.items.related_manager_cls = create_soft_delete_related_manager(Order.items.related_manager_cls)
配置完成后,仅order.items的关联查询会自动过滤软删除数据,其他关联逻辑不受影响。
内容的提问来源于stack exchange,提问作者Rudiger
相关产品推荐
相关产品推荐

