Django Related Through Models Not Using Soft Delete Model Manager
я пытаюсь получить только те строки в сквозной модели, которые не удалены, но получаю все строки, включая удаленные.
узнал, что это ошибка с использованием use_for_related_fields в менеджере моделей, согласно этой ссылке: https://code.djangoproject.com/ticket/17746
.
я пытаюсь реализовать систему следования/отмены, как на платформах социальных сетей
ниже приведен пример моего кода
class BasicModelQuerySet(models.QuerySet):
def delete(self):
return self.update(is_deleted = True, deleted_at = timezone.now())
def erase(self):
return super(BasicModelQuerySet, self).delete()
class BasicModelManager(models.Manager):
use_for_related_fields = True
def get_queryset(self):
return BasicModelQuerySet(self.model, self._db).filter(is_deleted = False).filter(deleted_at__isnull = True)
class BasicModel(models.Model):
deleted_at = models.DateTimeField(blank = True, null = True)
is_deleted = models.BooleanField(default = False)
objects = BasicModelManager()
everything = models.Manager()
class Meta:
abstract = True
class Listing(BasicModel):
watchers = models.ManyToManyField(User, through = 'Watching', related_name = 'watchers')
class Watching(BasicModel):
user = models.ForeignKey(User, on_delete = models.RESTRICT, related_name = 'watching')
listing = models.ForeignKey(Listing, on_delete = models.RESTRICT, related_name = 'spectators')
образцы таблиц
id | user |
-------------
1 | User A |
2 | User B |
id | listing |
----------------
1 | Listing A |
2 | Listing B |
# watchings table
id | user | listing | deleted_at | is_deleted |
------------------------------------------------------------
1 | User A | Listing A | | |
2 | User B | Listing A | 2022-02-25 11:07:18 | True |
3 | User B | Listing B | | |
listing = Listing.objects.get(id = 1)
# returns Listing A
listing.watchers.all()
# returns two rows [1, 2] instead of just 1
listing.watchers.through.objects.all()
# returns two rows [1, 3], which is wrong
как мне вернуть только те строки, которые не удалены для листинга? или мне нужно изменить дизайн и или не использовать сквозную модель?
- последующая вернет все
Usersдля листинга, которые присутствуют в вашей БД, поскольку вы не применяете никакого фильтра.
listing.watchers.all()
- здесь вы, похоже, совершаете ту же ошибку не фильтрации, помните, что в БД есть записи. вы не удалили их.
#listing.watchers.through.objects.all()
listing.watchers.through.objects.exclude(is_deleted=True)
Кроме того, что я считаю неправильным, это дополнительная таблица Watching, которая могла бы иметь смысл, если бы у вас было больше полей в этой таблице (хотя они не требуют, как вы сказали, это просто функция следовать/не следовать)