### Install django-safedelete using Pip Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/index.md This command installs the django-safedelete package from the Python Package Index (PyPI) using pip, the standard package installer for Python. Ensure you have pip installed and configured. ```default pip install django-safedelete ``` -------------------------------- ### Install django-safedelete from GitHub Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/index.md This command installs the django-safedelete package directly from its GitHub repository in editable mode. This is useful for development or when you need the latest unreleased version. The -e flag means the package will be linked directly to the source code. ```default pip install -e git://github.com/makinacorpus/django-safedelete.git#egg=django-safedelete ``` -------------------------------- ### Install and Configure Django SafeDelete Source: https://context7.com/makinacorpus/django-safedelete/llms.txt Installs the django-safedelete package via pip and configures it in Django's settings.py. It also shows optional settings for defining deleted field names and interpreting undeleted objects. ```python pip install django-safedelete # settings.py INSTALLED_APPS = [ 'safedelete', # ... other apps ] # Optional configuration SAFE_DELETE_INTERPRET_UNDELETED_OBJECTS_AS_CREATED = True SAFE_DELETE_FIELD_NAME = 'deleted' # Default field name SAFE_DELETE_CASCADED_FIELD_NAME = 'deleted_by_cascade' # Default cascade field name ``` -------------------------------- ### Add safedelete to Django INSTALLED_APPS Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/index.md After installing django-safedelete, you need to add 'safedelete' to the INSTALLED_APPS setting in your Django project's settings.py file. This makes the application's models and features available to your project. ```python INSTALLED_APPS = [ 'safedelete', [...] ] ``` -------------------------------- ### Implement Various Deletion Policies Source: https://context7.com/makinacorpus/django-safedelete/llms.txt Illustrates the usage of different deletion policies (SOFT_DELETE, SOFT_DELETE_CASCADE, HARD_DELETE, HARD_DELETE_NOCASCADE, NO_DELETE) across multiple related models. Includes examples of how each policy affects deletion behavior and how to force a specific policy. ```python from safedelete.models import SafeDeleteModel from safedelete.models import ( SOFT_DELETE, SOFT_DELETE_CASCADE, HARD_DELETE, HARD_DELETE_NOCASCADE, NO_DELETE ) from django.db import models class Order(SafeDeleteModel): _safedelete_policy = SOFT_DELETE_CASCADE order_number = models.CharField(max_length=50) customer = models.ForeignKey('Customer', on_delete=models.CASCADE) class OrderItem(SafeDeleteModel): _safedelete_policy = SOFT_DELETE order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='items') product = models.CharField(max_length=200) quantity = models.IntegerField() class AuditLog(SafeDeleteModel): _safedelete_policy = NO_DELETE # Cannot be deleted action = models.CharField(max_length=100) timestamp = models.DateTimeField(auto_now_add=True) # Example 1: SOFT_DELETE - only the object is masked item = OrderItem.objects.create(order=order, product="Widget", quantity=5) item.delete() # Only item is soft-deleted, order remains # Example 2: SOFT_DELETE_CASCADE - object and related objects are masked order = Order.objects.create(order_number="ORD-001", customer=customer) OrderItem.objects.create(order=order, product="Gadget", quantity=3) order.delete() # Order and all items are soft-deleted # Example 3: HARD_DELETE_NOCASCADE - conditional deletion category = Category.objects.create(name="Electronics") product = Product.objects.create(name="Laptop", category=category) category.delete() # Soft-deleted because product references it product.delete() # Hard-deleted category.delete() # Now hard-deleted since nothing references it # Example 4: Force a specific policy article.delete(force_policy=HARD_DELETE) # Force hard delete # Example 5: NO_DELETE policy log = AuditLog.objects.create(action="User login") log.delete() # Returns (0, {}) - nothing deleted ``` -------------------------------- ### Define Models with Soft Delete Policies Source: https://context7.com/makinacorpus/django-safedelete/llms.txt Demonstrates creating Django models that inherit from SafeDeleteModel and apply different deletion policies. Includes examples of basic soft delete, conditional hard delete, and cascade soft delete. ```python from django.db import models from safedelete.models import SafeDeleteModel from safedelete.models import SOFT_DELETE, HARD_DELETE_NOCASCADE, SOFT_DELETE_CASCADE # Basic soft delete model class Article(SafeDeleteModel): _safedelete_policy = SOFT_DELETE # Default policy title = models.CharField(max_length=200) content = models.TextField() author = models.ForeignKey('Author', on_delete=models.CASCADE) # Model with conditional hard delete class Category(SafeDeleteModel): _safedelete_policy = HARD_DELETE_NOCASCADE # Hard delete if no cascade name = models.CharField(max_length=100) # Model with cascade soft delete class Author(SafeDeleteModel): _safedelete_policy = SOFT_DELETE_CASCADE name = models.CharField(max_length=100) email = models.EmailField(unique=True) # Usage examples article = Article.objects.create( title="Django Tips", content="Soft delete is useful for...", author=author ) # Soft delete - object is masked but remains in database article.delete() # Returns (1, {'myapp.Article': 1}) # Object is not visible in default queryset Article.objects.filter(title="Django Tips").exists() # False # Object is visible in all_objects queryset Article.all_objects.filter(title="Django Tips").exists() # True # Object is visible in deleted_objects queryset Article.deleted_objects.filter(title="Django Tips").exists() # True # Check if deleted article.deleted # Returns datetime of deletion ``` -------------------------------- ### Usage Example: Deleting Objects with SafeDelete (Python) Source: https://github.com/makinacorpus/django-safedelete/blob/master/README.rst Illustrates how to use the safedelete functionality with the defined models. It shows the behavior of the delete() method when an object is referenced by other objects, resulting in a soft delete, versus when it is not referenced, resulting in a hard delete. ```python article1 = Article(name='article1') article1.save() article2 = Article(name='article2') article2.save() order = Order(name='order') order.save() order.articles.add(article1) # This article will be masked, but not deleted from the database as it is still referenced in an order. article1.delete() # This article will be deleted from the database. article2.delete() ``` -------------------------------- ### Handle SafeDelete Signals for Django Models Source: https://context7.com/makinacorpus/django-safedelete/llms.txt This snippet demonstrates how to use Django's signal system to hook into the pre-softdelete, post-softdelete, and post-undelete events for models inheriting from SafeDeleteModel. It includes logging examples for each signal. ```python from django.dispatch import receiver from safedelete.models import SafeDeleteModel, SOFT_DELETE from safedelete.signals import pre_softdelete, post_softdelete, post_undelete from django.db import models import logging logger = logging.getLogger(__name__) class Document(SafeDeleteModel): _safedelete_policy = SOFT_DELETE title = models.CharField(max_length=200) content = models.TextField() file_path = models.CharField(max_length=500) @receiver(pre_softdelete, sender=Document) def before_soft_delete(sender, instance, using, **kwargs): """Called before object is soft-deleted""" logger.info(f"About to soft-delete document: {instance.title}") # Perform pre-deletion tasks # e.g., backup file, notify users, etc. @receiver(post_softdelete, sender=Document) def after_soft_delete(sender, instance, using, **kwargs): """Called after object is soft-deleted""" logger.info(f"Document soft-deleted: {instance.title}") # Perform post-deletion tasks # e.g., archive file, send notifications, update indexes @receiver(post_undelete, sender=Document) def after_undelete(sender, instance, using, **kwargs): """Called after object is undeleted""" logger.info(f"Document restored: {instance.title}") # Perform restoration tasks # e.g., restore file access, notify users # Usage doc = Document.objects.create( title="Important Report", content="...", file_path="/docs/report.pdf" ) # Triggers pre_softdelete and post_softdelete signals doc.delete() # Triggers post_undelete signal doc.undelete() # Note: save() on a deleted object also triggers post_undelete doc = Document.deleted_objects.first() doc.save() # Triggers post_undelete ``` -------------------------------- ### Customize Model Admin with SafeDeleteAdmin in Python Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/admin.md This example demonstrates how to integrate `SafeDeleteAdmin` into your Django model administration. It customizes `list_display` to include highlighting for deleted objects and specifies a field for highlighting using `highlight_deleted_field`. This allows for better visibility and management of soft-deleted items directly within the admin interface. ```python from safedelete.admin import SafeDeleteAdmin, SafeDeleteAdminFilter, highlight_deleted class ContactAdmin(SafeDeleteAdmin): list_display = (highlight_deleted, "highlight_deleted_field", "first_name", "last_name", "email") + SafeDeleteAdmin.list_display list_filter = ("last_name", SafeDeleteAdminFilter,) + SafeDeleteAdmin.list_filter field_to_highlight = "id" ContactAdmin.highlight_deleted_field.short_description = ContactAdmin.field_to_highlight ``` -------------------------------- ### Define Models with SafeDeletePolicy in Django Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/index.md This example demonstrates how to define Django models that inherit from SafeDeleteModel and specify a custom deletion policy. The _safedelete_policy attribute controls the behavior when an object is deleted, offering options like HARD_DELETE_NOCASCADE which masks deletion if dependent objects exist. ```python from safedelete.models import SafeDeleteModel from safedelete.models import HARD_DELETE_NOCASCADE from django.db import models class Article(SafeDeleteModel): _safedelete_policy = HARD_DELETE_NOCASCADE name = models.CharField(max_length=100) class Order(SafeDeleteModel): _safedelete_policy = HARD_DELETE_NOCASCADE name = models.CharField(max_length=100) articles = models.ManyToManyField(Article) ``` -------------------------------- ### Implement Partial Unique Constraint for Active Objects in Django Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/models.md Demonstrates how to enforce unique constraints only on non-deleted (active) objects using Django's `UniqueConstraint` with a conditional `Q` object. This prevents conflicts with soft-deleted records. The example defines a 'unique_active_name' constraint on the 'name' field. ```python class Post(SafeDeleteModel): name = models.CharField(max_length=100) class Meta: constraints = [ UniqueConstraint( fields=['name'], condition=Q(deleted__isnull=True), name='unique_active_name' ), ] ``` -------------------------------- ### Generate Documentation with tox (Shell) Source: https://github.com/makinacorpus/django-safedelete/blob/master/README.rst Command to generate the project's documentation locally using tox, typically for development or testing documentation builds. ```bash tox -e docs ``` -------------------------------- ### Working with SafeDelete Managers in Django Source: https://context7.com/makinacorpus/django-safedelete/llms.txt Demonstrates how to define and use custom SafeDelete managers in Django models. This includes setting specific visibility policies (e.g., making deleted objects visible by primary key) and utilizing default managers like `objects`, `all_objects`, and `deleted_objects` for different query scopes. It also shows how to use related manager methods and perform updates or creations considering soft-deleted states. ```python from safedelete.models import SafeDeleteModel from safedelete.managers import SafeDeleteManager from safedelete.config import DELETED_VISIBLE_BY_PK from django.db import models # Custom manager with specific visibility class CustomManager(SafeDeleteManager): _safedelete_visibility = DELETED_VISIBLE_BY_PK class Product(SafeDeleteModel): name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) # Default managers # objects = SafeDeleteManager() # Non-deleted only # all_objects = SafeDeleteAllManager() # All objects # deleted_objects = SafeDeleteDeletedManager() # Deleted only custom_objects = CustomManager() # Create and delete products product1 = Product.objects.create(name="Laptop", price=999.99) product2 = Product.objects.create(name="Mouse", price=29.99) product1.delete() # Default manager - only non-deleted Product.objects.all() # [] Product.objects.count() # 1 # All objects manager - includes deleted Product.all_objects.all() # [, ] Product.all_objects.count() # 2 # Deleted objects manager - only deleted Product.deleted_objects.all() # [] Product.deleted_objects.count() # 1 # Related manager methods Product.objects.all_with_deleted() # [, ] Product.objects.deleted_only() # [] # Update or create with soft-deleted objects product, created = Product.objects.update_or_create( name="Laptop", defaults={'price': 1099.99} ) # If SAFE_DELETE_INTERPRET_UNDELETED_OBJECTS_AS_CREATED=True, created=True # Otherwise created=False (object was revived) # Filtering with deleted field Product.all_objects.filter(deleted__isnull=False) # Deleted objects Product.all_objects.filter(deleted__isnull=True) # Non-deleted objects ``` -------------------------------- ### Handling Soft-Deleted Objects with update_or_create in Django SafeDelete Source: https://context7.com/makinacorpus/django-safedelete/llms.txt Demonstrates how Django SafeDelete's update_or_create method can revive and update soft-deleted objects. It highlights the behavior regarding slug conflicts and the optional interpretation of revived objects as newly created. ```python from django.core.exceptions import ValidationError # Assuming BlogPost and author are defined elsewhere # even though post1 is soft-deleted try: post2 = BlogPost.objects.create( title="Another Post", slug="my-post", # Same slug as deleted post author=author, status='published' ) except ValidationError as e: print(f"Validation error: {e}") # update_or_create revives soft-deleted objects post, created = BlogPost.objects.update_or_create( slug="my-post", defaults={'status': 'draft'} ) # post1 is undeleted and updated, created=False # (or created=True if SAFE_DELETE_INTERPRET_UNDELETED_OBJECTS_AS_CREATED=True) ``` -------------------------------- ### Configure SafeDeleteManager Visibility (Python) Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/managers.md Demonstrates how to define a custom manager inheriting from SafeDeleteManager and set its _safedelete_visibility attribute to DELETED_VISIBLE_BY_PK. This allows the manager to return deleted objects when accessed by their primary key. ```python from safedelete.models import SafeDeleteModel from safedelete.managers import SafeDeleteManager from django.db import models # Assuming DELETED_VISIBLE_BY_PK is defined elsewhere, e.g., from safedelete.constants DELETED_VISIBLE_BY_PK = 1 # Placeholder definition SOFT_DELETE = 1 # Placeholder definition class MyModelManager(SafeDeleteManager): _safedelete_visibility = DELETED_VISIBLE_BY_PK class MyModel(SafeDeleteModel): _safedelete_policy = SOFT_DELETE my_field = models.TextField() objects = MyModelManager() ``` -------------------------------- ### Custom Queryset and Unique Constraints with SafeDelete Source: https://context7.com/makinacorpus/django-safedelete/llms.txt This snippet demonstrates creating custom querysets and managers for models inheriting from SafeDeleteModel, enabling filtered queries and ensuring unique constraints function correctly even with soft-deleted objects. ```python from safedelete.models import SafeDeleteModel, SOFT_DELETE from safedelete.managers import SafeDeleteManager from safedelete.queryset import SafeDeleteQueryset from django.db import models from django.core.exceptions import ValidationError class CustomQueryset(SafeDeleteQueryset): def published(self): return self.filter(status='published') def by_author(self, author): return self.filter(author=author) class CustomManager(SafeDeleteManager): _queryset_class = CustomQueryset class BlogPost(SafeDeleteModel): _safedelete_policy = SOFT_DELETE title = models.CharField(max_length=200) slug = models.SlugField(unique=True) # Unique constraint author = models.ForeignKey('Author', on_delete=models.CASCADE) status = models.CharField( max_length=20, choices=[('draft', 'Draft'), ('published', 'Published')] ) objects = CustomManager() class Meta: unique_together = [['author', 'title']] # Composite unique constraint # Custom queryset methods BlogPost.objects.published() # All published posts BlogPost.objects.by_author(author).published() # Published posts by author # Unique constraints work with soft-deleted objects post1 = BlogPost.objects.create( title="My Post", slug="my-post", author=author, status='published' ) post1.delete() # This would raise ValidationError due to unique slug constraint ``` -------------------------------- ### Customize SOFT_DELETE Policy Logic in Python Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/models.md Allows customization of the SOFT_DELETE policy's delete logic by overwriting the `soft_delete_policy_action` function. Users can add pre-delete or post-delete operations. This function expects keyword arguments and returns the delete response. ```python def soft_delete_policy_action(self, **kwargs): # Insert here custom pre delete logic delete_response = super().soft_delete_policy_action(**kwargs) # Insert here custom post delete logic return delete_response ``` -------------------------------- ### SafeDeleteManager get_soft_delete_policies() Static Method (Python) Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/managers.md Shows the usage of the static method get_soft_delete_policies() on SafeDeleteManager. This method returns all defined policies that signify some form of soft deletion within the application. ```python from safedelete.managers import SafeDeleteManager # Assuming SOFT_DELETE and other policies are defined policies = SafeDeleteManager.get_soft_delete_policies() print(policies) ``` -------------------------------- ### Configure SafeDeleteAdmin for Django Models Source: https://context7.com/makinacorpus/django-safedelete/llms.txt This snippet shows how to integrate SafeDeleteAdmin with a Django model to enable soft deletion, including custom list displays, filters, and actions. It utilizes Django's admin site and safedelete's admin extensions. ```python from django.contrib import admin from safedelete.admin import SafeDeleteAdmin, SafeDeleteAdminFilter, highlight_deleted from safedelete.models import SafeDeleteModel, SOFT_DELETE from django.db import models class Contact(SafeDeleteModel): _safedelete_policy = SOFT_DELETE first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) email = models.EmailField() phone = models.CharField(max_length=20) @admin.register(Contact) class ContactAdmin(SafeDeleteAdmin): # Include deleted status in list display list_display = ( highlight_deleted, 'first_name', 'last_name', 'email', 'phone', ) + SafeDeleteAdmin.list_display # Add filter for deleted status list_filter = ( 'last_name', SafeDeleteAdminFilter, ) + SafeDeleteAdmin.list_filter # Optional: highlight a specific field for deleted objects field_to_highlight = 'email' # Available actions: # - undelete_selected: Restore soft-deleted objects # - hard_delete_soft_deleted: Permanently remove soft-deleted objects actions = SafeDeleteAdmin.actions + ['custom_action'] def custom_action(self, request, queryset): # Custom admin action pass custom_action.short_description = "Custom action" # In the admin interface: # 1. Deleted objects appear in red with the highlight_deleted formatter # 2. Use SafeDeleteAdminFilter to show/hide deleted objects # 3. Select deleted objects and use "Undelete selected" action # 4. Select soft-deleted objects and use "Hard delete" action to permanently remove ``` -------------------------------- ### SafeDeleteQueryset Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/queryset.md The SafeDeleteQueryset class provides methods for managing soft-deleted objects within a Django application using the safedelete library. ```APIDOC ## SafeDeleteQueryset Class ### Description Default queryset for the SafeDeleteManager. Takes care of "lazily evaluating" safedelete QuerySets. QuerySets passed within the `SafeDeleteQueryset` will have all of the models available. The deleted policy is evaluated at the very end of the chain when the QuerySet itself is evaluated. ### Methods #### `as_manager()` * **Description**: Override as_manager behavior to ensure we create a SafeDeleteManager. * **Method**: classmethod * **Endpoint**: N/A #### `delete(force_policy=None)` * **Description**: Overrides bulk delete behavior. The current implementation loses performance on bulk deletes in order to safely delete objects according to the deletion policies set. * **Method**: Instance Method * **Endpoint**: N/A * **Parameters**: * **force_policy** (int) - Optional - The deletion policy to force. * **Response Example**: ```json { "count": 5, "deleted": { "safedelete.SoftDelete": 5 } } ``` #### `undelete(force_policy=None)` * **Description**: Undelete all soft deleted models. The current implementation loses performance on bulk undeletes in order to call the pre/post-save signals. * **Method**: Instance Method * **Endpoint**: N/A * **Parameters**: * **force_policy** (int) - Optional - The deletion policy to force. * **Response Example**: ```json { "count": 5, "undeleted": { "safedelete.SoftDelete": 5 } } ``` #### `all(force_visibility=None)` * **Description**: Override so related managers can also see the deleted models. A model’s m2m field does not easily have access to all_objects and so setting force_visibility to True is a way of getting all of the models. It is not recommended to use force_visibility outside of related models because it will create a new queryset. * **Method**: Instance Method * **Endpoint**: N/A * **Parameters**: * **force_visibility** (bool) - Optional - Force a deletion visibility. * **Return Type**: _QS (QuerySet instance) #### `filter(*args, **kwargs)` * **Description**: Return a new QuerySet instance with the args ANDed to the existing set. * **Method**: Instance Method * **Endpoint**: N/A * **Parameters**: * ***args**: Variable length argument list. * ****kwargs**: Arbitrary keyword arguments. * **Return Type**: _QS (QuerySet instance) ``` -------------------------------- ### Bulk Operations and Undelete with Django SafeDelete Source: https://context7.com/makinacorpus/django-safedelete/llms.txt Covers performing bulk operations such as soft deletion and undeletion on multiple objects using Django SafeDelete's QuerySet methods. It illustrates how to undelete individual objects and entire querysets, how to save a soft-deleted object without undeleting it using `keep_deleted=True`, and demonstrates cascade undelete behavior for related models. ```python from safedelete.models import SafeDeleteModel, SOFT_DELETE from django.db import models class Task(SafeDeleteModel): _safedelete_policy = SOFT_DELETE title = models.CharField(max_length=200) completed = models.BooleanField(default=False) priority = models.IntegerField(default=1) # Create multiple tasks Task.objects.bulk_create([ Task(title="Task 1", priority=1), Task(title="Task 2", priority=2), Task(title="Task 3", priority=3), ]) # Bulk soft delete deleted_count, deleted_dict = Task.objects.filter(priority__lt=3).delete() # deleted_count = 2 # deleted_dict = {'myapp.Task': 2} # Undelete individual object task = Task.deleted_objects.first() task.undelete() # Returns (1, {'myapp.Task': 1}) task.deleted # None # Bulk undelete queryset undeleted_count, undeleted_dict = Task.deleted_objects.filter( priority=2 ).undelete() # undeleted_count = 1 # undeleted_dict = {'myapp.Task': 1} # Save without undeleting (keep deleted status) task = Task.deleted_objects.first() task.title = "Updated title" task.save(keep_deleted=True) # Remains deleted task.deleted # Still has deletion timestamp # Cascade undelete class Project(SafeDeleteModel): _safedelete_policy = SOFT_DELETE_CASCADE name = models.CharField(max_length=100) class Sprint(SafeDeleteModel): _safedelete_policy = SOFT_DELETE_CASCADE project = models.ForeignKey(Project, on_delete=models.CASCADE) name = models.CharField(max_length=100) project = Project.objects.create(name="MyProject") sprint = Sprint.objects.create(project=project, name="Sprint 1") project.delete() # Both project and sprint soft-deleted project.undelete() # Both project and sprint undeleted ``` -------------------------------- ### Define Models with SafeDeletePolicy (Python) Source: https://github.com/makinacorpus/django-safedelete/blob/master/README.rst Demonstrates how to define Django models that inherit from SafeDeleteModel and configure their deletion policy. The _safedelete_policy attribute can be set to HARD_DELETE_NOCASCADE to ensure objects are hard-deleted unless their deletion would affect dependent objects, in which case they are soft-deleted. ```python from safedelete.models import SafeDeleteModel from safedelete.models import HARD_DELETE_NOCASCADE class Article(SafeDeleteModel): _safedelete_policy = HARD_DELETE_NOCASCADE name = models.CharField(max_length=100) class Order(SafeDeleteModel): _safedelete_policy = HARD_DELETE_NOCASCADE name = models.CharField(max_length=100) articles = models.ManyToManyField(Article) ``` -------------------------------- ### SafeDeleteManager update_or_create() Behavior (Python) Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/managers.md Explains the modified update_or_create() behavior in SafeDeleteManager. When an existing soft-deleted record is found, it's 'revived' by setting the deleted field to None instead of updating it, ensuring visibility. Note the behavior regarding the 'created' return value based on Django settings. ```python from safedelete.managers import SafeDeleteManager from safedelete.models import SafeDeleteModel from django.db import models class MyModelManager(SafeDeleteManager): def update_or_create(self, defaults=None, **kwargs): # Logic to handle soft-deleted objects during update_or_create # ... implementation details ... return super().update_or_create(defaults, **kwargs) class MyModel(SafeDeleteModel): my_field = models.TextField() objects = MyModelManager() ``` -------------------------------- ### SafeDeleteManager get_queryset() Method (Python) Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/managers.md Illustrates overriding the get_queryset() method in a custom SafeDeleteManager subclass. This is used to customize the behavior of the Manager by returning a custom QuerySet object, allowing for additional filters on deleted and non-deleted objects. ```python from safedelete.managers import SafeDeleteManager from safedelete.queryset import SafeDeleteQueryset # Assuming this is the base queryset class class CustomSafeDeleteManager(SafeDeleteManager): def get_queryset(self): # Return a custom queryset, possibly inheriting from SafeDeleteQueryset return SafeDeleteQueryset(self.model, using=self._db) ``` -------------------------------- ### SafeDeleteAllManager Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/managers.md A specialized manager that always shows all objects, including soft-deleted ones. ```APIDOC ## SafeDeleteAllManager ### Description SafeDeleteManager with `_safedelete_visibility` set to `DELETED_VISIBLE`. This manager is used for `safedelete.models.SafeDeleteModel.all_objects`. ### Class safedelete.managers.SafeDeleteAllManager ### Notes This manager ensures that all objects, whether deleted or not, are visible in querysets. ``` -------------------------------- ### SafeDeleteDeletedManager Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/managers.md A specialized manager that only shows soft-deleted objects. ```APIDOC ## SafeDeleteDeletedManager ### Description SafeDeleteManager with `_safedelete_visibility` set to `DELETED_ONLY_VISIBLE`. This manager is used for `safedelete.models.SafeDeleteModel.deleted_objects`. ### Class safedelete.managers.SafeDeleteDeletedManager ### Notes This manager filters querysets to only include objects that have been soft-deleted. ``` -------------------------------- ### SafeDeleteManager Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/managers.md The default manager for SafeDeleteModel. It controls the visibility of deleted objects based on the `_safedelete_visibility` attribute. ```APIDOC ## SafeDeleteManager ### Description Default manager for the SafeDeleteModel. It can return deleted objects if they are accessed by primary key when `_safedelete_visibility` is set to `DELETED_VISIBLE_BY_PK`. ### Class safedelete.managers.SafeDeleteManager ### Attributes * **`_safedelete_visibility`** (enum: `DELETED_INVISIBLE`, `DELETED_VISIBLE_BY_PK`) - Defines what happens when querying masked objects. Defaults to `DELETED_INVISIBLE`. * **`_queryset_class`** (class) - Defines which class for queryset should be used. Defaults to `SafeDeleteQueryset`. ### Methods * **`get_queryset()`** Returns a new QuerySet object. Subclasses can override this method to customize the behavior of the Manager. * **`all_with_deleted()`** → QuerySet Shows all models, including soft-deleted models. Useful for related managers. * **`deleted_only()`** → QuerySet Shows only the soft-deleted models. Useful for related managers. * **`all(**kwargs)`** → QuerySet Passes kwargs to `SafeDeleteQueryset.all()`. The `force_visibility` argument can be used to show deleted models. * **`update_or_create(defaults=None, **kwargs)`** → Tuple[Model, bool] Handles updating or creating model instances. If an object is soft-deleted and meets unique constraints, it will be revived instead of updated. Returns `(instance, created)`. * **`get_soft_delete_policies()`** (static) Returns all states that signify some kind of soft-delete. ``` -------------------------------- ### Django Template for Undelete Confirmation Source: https://github.com/makinacorpus/django-safedelete/blob/master/safedelete/templates/safedelete/undelete_selected_confirmation.html This Django template extends the default delete confirmation page to handle undeletion. It displays the objects to be undeleted and their related objects, prompting the user for confirmation. It uses Django's translation and object listing tags. ```django {% extends "admin/delete_selected_confirmation.html" %} {% load i18n l10n %} {% block content %} {% blocktrans %}Are you sure you want to undelete the selected {{ objects_name }}?{% endblocktrans %} {{ queryset|unordered_list }} {% csrf_token %} {% for obj in queryset %} {% endfor %} {% blocktrans %}Related objects{% endblocktrans %} {% for related in related_list %} {{ related | unordered_list }} {% endfor %} {% endblock %} ``` -------------------------------- ### Django Template for Hard Delete Confirmation Source: https://github.com/makinacorpus/django-safedelete/blob/master/safedelete/templates/safedelete/hard_delete_selected_confirmation.html This Django template displays a confirmation message before hard-deleting selected objects. It extends the default delete confirmation template and includes CSRF token for security. It iterates through related objects to inform the user about potential data loss. ```django {% extends "admin/delete_selected_confirmation.html" %} {% load i18n l10n %} {% block content %} {% blocktrans %}Are you sure you want to hard delete the selected {{ objects_name }}?{% endblocktrans %} {{ queryset|unordered_list }} {% csrf_token %} {% for obj in queryset %} {% endfor %} {% blocktrans %}Related objects{% endblocktrans %} {% for related in related_list %} {{ related | unordered_list }} {% endfor %} {% endblock %} ``` -------------------------------- ### Disabling Cascade Tracking in Django SafeDelete Models Source: https://context7.com/makinacorpus/django-safedelete/llms.txt Illustrates how to disable the 'deleted_by_cascade' field for specific models using Django SafeDelete. This prevents the model from tracking objects deleted through cascade operations, simplifying cascade management. ```python from django.db import models from safedelete.models import SafeDeleteModel class SimpleModel(SafeDeleteModel): deleted_by_cascade = None # Disable cascade tracking name = models.CharField(max_length=100) ``` -------------------------------- ### Check for Unique Constraints in SafeDeleteModel Source: https://github.com/makinacorpus/django-safedelete/blob/master/docs/models.md This class method, 'has_unique_fields', is part of the SafeDeleteModel. It checks if a model has any fields with a unique constraint set (unique=True) or if there are sets of field names that together must be unique. This is useful for data integrity validation. ```python from safedelete.models import SafeDeleteModel # Assuming MyModel inherits from SafeDeleteModel if MyModel.has_unique_fields(): print("Model has unique constraints.") else: print("Model does not have unique constraints.") ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.