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

как мне вернуть только те строки, которые не удалены для листинга? или мне нужно изменить дизайн и или не использовать сквозную модель?

  1. последующая вернет все Users для листинга, которые присутствуют в вашей БД, поскольку вы не применяете никакого фильтра.
listing.watchers.all()
  1. здесь вы, похоже, совершаете ту же ошибку не фильтрации, помните, что в БД есть записи. вы не удалили их.
#listing.watchers.through.objects.all()
listing.watchers.through.objects.exclude(is_deleted=True)

Кроме того, что я считаю неправильным, это дополнительная таблица Watching, которая могла бы иметь смысл, если бы у вас было больше полей в этой таблице (хотя они не требуют, как вы сказали, это просто функция следовать/не следовать)

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