Мягкое удаление в отношениях "многие-ко-многим" с помощью сквозной модели в Django

Я столкнулся с проблемой в своем проекте Django, связанной с мягким удалением в отношениях "многие-ко-многим" с использованием сквозной модели. Буду признателен за любую помощь или совет по решению этой проблемы.

В моем приложении есть три модели: Author, Book и BookAuthor. Отношения "многие-ко-многим" между Author и Book определяются через модель BookAuthor. Вот определения моих моделей:

from django.db import models

class Author(SoftDeleteModel):
    name = models.CharField(max_length=100)

class Book(SoftDeleteModel):
    title = models.CharField(max_length=200)
    authors = models.ManyToManyField(Author, through='BookAuthor', related_name='books')

class BookAuthor(SoftDeleteModel):
    book = models.ForeignKey(Book, on_delete=models.CASCADE)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

    class Meta:
        # Other necessary meta definitions
        pass

Проблема возникает, когда я мягко удаляю отношение в модели BookAuthor, а затем пытаюсь получить доступ к книгам автора с помощью запроса author.books.all(). Даже если я мягко удалил отношение в BookAuthor, я все равно вижу все книги, связанные с автором.

Я использую пакет django-soft-delete (https://pypi.org/project/django-soft-delete/),

У кого-нибудь есть предложения по решению этой проблемы и обеспечению того, чтобы мягко удаленные отношения не отображались при доступе через отношения "многие-ко-многим"?

Любая помощь или совет будут очень признательны! Заранее спасибо!

Вы забыли подклассифицировать SoftDeleteModel, установка пакета ничего не дает, его нужно реально использовать

Цитируется по их документации

class Article(SoftDeleteModel):
    title = models.CharField(max_length=100)
    
    # Following fields will be added automatically
    # is_deleted
    # deleted_at
    
    # Following managers will be added automatically
    # objects = SoftDeleteManager()
    # deleted_objects = DeletedManager()
    # global_objects = GlobalManager()

После некоторых дальнейших исследований мне удалось решить эту проблему, изменив SoftDeleteManager, предоставляемый пакетом django-soft-delete. Вот модифицированный SoftDeleteManager с дополнительной логикой для фильтрации мягко удаленных отношений при обращении к ним через отношения "многие-ко-многим":

from django.db import models
from soft_delete.managers import SoftDeleteQuerySet

class SoftDeleteManager(models.Manager):
    def get_queryset(self):
        return SoftDeleteQuerySet(self.model, self._db).filter(is_deleted=False)

    def _apply_soft_delete_filter(self, queryset):
        return queryset.filter(is_deleted=False)

    def _apply_soft_delete_filter_if_needed(self, queryset):
        if self.__class__.__name__ == 'ManyRelatedManager':
            related_name = getattr(self.through, self.target_field_name).field._related_name
            filter_kwargs = {f'{related_name}__is_deleted': False}
            queryset = queryset.filter(is_deleted=False, **filter_kwargs)
        return queryset.filter(is_deleted=False)

    def all(self, *args, **kwargs):
        queryset = self.get_queryset()
        return self._apply_soft_delete_filter_if_needed(queryset)

    def filter(self, *args, **kwargs):
        queryset = self.get_queryset()
        queryset = self._apply_soft_delete_filter_if_needed(queryset)
        return queryset.filter(*args, **kwargs)

    def get(self, *args, **kwargs):
        queryset = self.get_queryset()
        queryset = self._apply_soft_delete_filter_if_needed(queryset)
        return queryset.get(*args, **kwargs)

Эта модификация гарантирует, что мягко удаленные отношения не будут отображаться при доступе к ним через отношения "многие-ко-многим". Если у вас возникнут какие-либо проблемы или дополнительные вопросы, не стесняйтесь спрашивать!

Вернуться на верх