Мягкое удаление в отношениях "многие-ко-многим" с помощью сквозной модели в 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)
Эта модификация гарантирует, что мягко удаленные отношения не будут отображаться при доступе к ним через отношения "многие-ко-многим". Если у вас возникнут какие-либо проблемы или дополнительные вопросы, не стесняйтесь спрашивать!