django fixes restored defautl delte cofnruiiamtions and working accoutna dn sites deletion with cascading
This commit is contained in:
@@ -565,6 +565,114 @@ class Site(SoftDeletableModel, AccountBaseModel):
|
||||
def can_add_sector(self):
|
||||
"""Check if site can add another sector based on plan limits."""
|
||||
return self.get_active_sectors_count() < self.get_max_sectors_limit()
|
||||
|
||||
def soft_delete(self, user=None, reason=None, retention_days=None, cascade=True):
|
||||
"""
|
||||
Soft delete site and optionally cascade to all related objects.
|
||||
|
||||
Args:
|
||||
user: User performing the deletion
|
||||
reason: Reason for deletion
|
||||
retention_days: Days to retain before permanent deletion
|
||||
cascade: If True, cascade soft-delete to all related objects
|
||||
"""
|
||||
if cascade:
|
||||
self._cascade_delete_related(user=user, reason=reason, retention_days=retention_days, hard_delete=False)
|
||||
|
||||
return super().soft_delete(user=user, reason=reason, retention_days=retention_days)
|
||||
|
||||
def _cascade_delete_related(self, user=None, reason=None, retention_days=None, hard_delete=False):
|
||||
"""
|
||||
Delete all related objects when site is deleted.
|
||||
For soft delete: soft-deletes objects with SoftDeletableModel, hard-deletes others
|
||||
For hard delete: hard-deletes everything
|
||||
"""
|
||||
from igny8_core.common.soft_delete import SoftDeletableModel
|
||||
|
||||
# List of related objects to delete (in order to avoid FK constraint issues)
|
||||
related_names = [
|
||||
# Content & Planning related (delete first due to dependencies)
|
||||
'contentclustermap_set',
|
||||
'contentattribute_set',
|
||||
'contenttaxonomy_set',
|
||||
'content_set',
|
||||
'images_set',
|
||||
'contentideas_set',
|
||||
'tasks_set',
|
||||
'keywords_set',
|
||||
'clusters_set',
|
||||
# Automation
|
||||
'automation_runs',
|
||||
'automation_config',
|
||||
# Publishing & Integration
|
||||
'sync_events',
|
||||
'publishing_settings',
|
||||
'publishingrecord_set',
|
||||
'deploymentrecord_set',
|
||||
'integrations',
|
||||
# Notifications
|
||||
'notifications',
|
||||
# Settings & AI
|
||||
# Core
|
||||
'sectors',
|
||||
'user_access',
|
||||
]
|
||||
|
||||
for related_name in related_names:
|
||||
try:
|
||||
related = getattr(self, related_name, None)
|
||||
if related is None:
|
||||
continue
|
||||
|
||||
# Handle OneToOne fields
|
||||
if hasattr(related, 'pk'):
|
||||
# It's a single object (OneToOneField)
|
||||
if hard_delete:
|
||||
related.hard_delete() if hasattr(related, 'hard_delete') else related.delete()
|
||||
elif isinstance(related, SoftDeletableModel):
|
||||
related.soft_delete(user=user, reason=reason, retention_days=retention_days)
|
||||
else:
|
||||
# Non-soft-deletable single object - hard delete
|
||||
related.delete()
|
||||
else:
|
||||
# It's a RelatedManager (ForeignKey)
|
||||
queryset = related.all()
|
||||
if queryset.exists():
|
||||
if hard_delete:
|
||||
# Hard delete all
|
||||
if hasattr(queryset, 'hard_delete'):
|
||||
queryset.hard_delete()
|
||||
else:
|
||||
for obj in queryset:
|
||||
if hasattr(obj, 'hard_delete'):
|
||||
obj.hard_delete()
|
||||
else:
|
||||
obj.delete()
|
||||
else:
|
||||
# Soft delete if supported, otherwise hard delete
|
||||
model = queryset.model
|
||||
if issubclass(model, SoftDeletableModel):
|
||||
for obj in queryset:
|
||||
obj.soft_delete(user=user, reason=reason, retention_days=retention_days)
|
||||
else:
|
||||
queryset.delete()
|
||||
except Exception as e:
|
||||
# Log but don't fail - some relations may not exist
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.warning(f"Failed to delete related {related_name} for site {self.pk}: {e}")
|
||||
|
||||
def hard_delete_with_cascade(self, using=None, keep_parents=False):
|
||||
"""
|
||||
Permanently delete the site and ALL related objects.
|
||||
This bypasses soft-delete and removes everything from the database.
|
||||
USE WITH CAUTION - this cannot be undone!
|
||||
"""
|
||||
# Cascade hard-delete all related objects first
|
||||
self._cascade_delete_related(hard_delete=True)
|
||||
|
||||
# Finally hard-delete the site itself
|
||||
return super().hard_delete(using=using, keep_parents=keep_parents)
|
||||
|
||||
|
||||
class Industry(models.Model):
|
||||
|
||||
Reference in New Issue
Block a user