Django如何编写无需调用方法即自带预过滤的自定义QuerySet
实现方案说明
完全可以实现你需要的效果,仅需重写自定义QuerySet的默认查询方法,配合as_manager()生成的管理器即可全局自动应用过滤规则,无需每次查询额外调用方法。
具体实现步骤
- 定义自定义QuerySet类,重写
all()方法,在返回结果前注入你的过滤规则。示例为自动过滤掉已逻辑删除(is_deleted=True)的条目:
from django.db import models class AutoFilterQuerySet(models.QuerySet): def all(self): # 先调用父类原生方法获取全量查询集,再应用过滤规则 return super().all().filter(is_deleted=False)
- 在模型中绑定该QuerySet作为默认管理器:
class YourBusinessModel(models.Model): name = models.CharField(max_length=64) is_deleted = models.BooleanField(default=False, verbose_name="是否删除") # 其他业务字段... # 绑定自定义QuerySet生成的管理器,替换默认管理器 objects = AutoFilterQuerySet.as_manager()
完成上述配置后,所有默认查询都会自动带上is_deleted=False的过滤条件,包括YourBusinessModel.objects.all()、YourBusinessModel.objects.filter(name="xxx")、YourBusinessModel.objects.get(id=1)等常用查询,无需额外调用任何自定义方法。
注意事项
- 如果你需要偶尔查询被过滤的全量数据,可以在自定义QuerySet中新增一个跳过过滤的方法:
需要查询全量时调用class AutoFilterQuerySet(models.QuerySet): def all(self): return super().all().filter(is_deleted=False) def include_deleted(self): # 直接返回原生全量查询集,跳过默认过滤 return super().all()YourBusinessModel.objects.include_deleted()即可。 - Django Admin默认会使用模型的默认管理器,如果你希望Admin后台可以看到所有条目,可以给模型额外加一个原生管理器,在Admin类中指定使用该管理器即可:
class YourBusinessModel(models.Model): # 字段定义同上 objects = AutoFilterQuerySet.as_manager() # 额外保留原生全量管理器,供Admin等特殊场景使用 raw_objects = models.Manager() - 不要直接修改
filter、exclude等底层链式方法,重写all()是兼容性最好的实现方式,Django所有查询方法最终都会基于all()返回的查询集执行。
内容的提问来源于stack exchange,提问作者samfrances
相关产品推荐
相关产品推荐

