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

如何查询SoftDeletableModel含软删除对象?替代自制方案遇阻

Solution for Adding all_with_deleted to django-model-utils SoftDeletableModel

Alright, let's break down how to solve this. You're right that the default SoftDeletableManagerMixin in django-model-utils only filters out soft-deleted objects in its get_queryset method—there's no built-in all_with_deleted functionality. But since you need access to those deleted records for cross-node notifications in your decentralized architecture, here are a couple of clean, maintainable solutions:

1. Custom Manager with all_with_deleted and deleted Methods

The simplest approach is to extend the existing SoftDeletableManagerMixin to add the methods you need. This preserves the default behavior of hiding soft-deleted objects while giving you explicit access when you need it.

from django.db import models
from model_utils.managers import SoftDeletableManagerMixin, SoftDeletableManager

class CustomSoftDeletableManager(SoftDeletableManagerMixin, models.Manager):
    def all_with_deleted(self):
        # Bypass the soft-delete filter by calling the parent of SoftDeletableManagerMixin
        return super(SoftDeletableManagerMixin, self).get_queryset()
    
    def deleted(self):
        # Optional: Convenience method to fetch only soft-deleted objects
        return self.all_with_deleted().filter(is_removed=True)

# Use this manager in your model
from model_utils.models import SoftDeletableModel

class YourDecentralizedModel(SoftDeletableModel):
    # Your model fields go here (e.g., name, created_at, etc.)
    name = models.CharField(max_length=100)
    
    # Replace the default manager with your custom one
    objects = CustomSoftDeletableManager()

How to Use It:

  • For normal operations (where you don't want soft-deleted objects), use YourDecentralizedModel.objects.all() as usual—it will still exclude deleted records.
  • When you need to process soft-deleted objects for cross-node notifications, call YourDecentralizedModel.objects.deleted() to get only the deleted entries, or all_with_deleted() to get every record (deleted and active).

2. Abstract Base Class for Reusability

If you have multiple models that need this functionality, create an abstract base model so you don't repeat code across your project:

class BaseSoftDeletableModel(SoftDeletableModel):
    objects = CustomSoftDeletableManager()
    
    class Meta:
        abstract = True

# Now inherit from this base model for all your decentralized models
class UserData(BaseSoftDeletableModel):
    # Your fields
    email = models.EmailField(unique=True)

class DeviceRecord(BaseSoftDeletableModel):
    # Your fields
    device_id = models.CharField(max_length=50)

Key Notes for Your Decentralized Setup

  • Avoid Overusing all_with_deleted: Keep the default manager's behavior intact for most business logic to prevent accidental exposure of deleted data. Only use deleted() or all_with_deleted() specifically in your cross-node notification workflows.
  • Track Processed Deletions: Consider adding a notification_sent boolean field to your models (or a separate audit log) to mark when you've already sent a deletion notification to other nodes. This prevents duplicate notifications.
  • Test Edge Cases: Make sure to write tests that verify:
    • Normal queries exclude soft-deleted objects
    • all_with_deleted() returns all records
    • deleted() returns only soft-deleted records

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:03:13