Как связать модель менеджеров? - PullRequest
2 голосов
/ 08 января 2020

У меня есть две абстрактные модели:

class SoftDeleteModel(models.Model):
    objects = SoftDeletableManager()

    class Meta:
        abstract = True


class BookAwareModel(models.Model):
    book = models.ForeignKey(Book)

    class Meta:
        abstract = True

Я часто использую эти модели вместе для DRY целей, например:

class MyNewModel(SoftDeleteModel, BookAwareModel):

В SoftDeleteModel есть собственный менеджер SoftDeletableManager():

class SoftDeletableManager(models.Manager):

    def get_queryset(self):

        return super().get_queryset().filter(is_removed=False)

Если я хочу расширить абстрактную модель BookAware, добавив фильтр набора запросов к Books, сохраняя при этом SoftDeletableManager(), как бы я go об этом сказал?

Например, я не могу добавить objects = BookManager() к BookAwareModel, потому что он перезапишет SoftDeletableManager.

1 Ответ

1 голос
/ 08 января 2020

Немного поиграв с вашим кодом, я нашел три возможных решения, которые, кажется, работают (согласно моим тестам):

Вариант 1 :

Создать комбинированный менеджер, который используется при определении вашей конкретной MyNewModel и использует его для этой модели:

class CombiManager(SoftDeletableManager, BookAwareManager):

    def get_queryset(self):
        qs1 = SoftDeletableManager.get_queryset(self)
        qs2 = BookAwareManager.get_queryset(self)
        return qs1.intersection(qs2)

, а затем

class MyNewModel(SoftDeleteModel, BookAwareModel):

    objects = CombiManager()

Опция 2:

Создайте менеджер для модели BookAware в качестве подкласса SoftDeleteableManager

class BookAwareManager(SoftDeletableManager):

    def get_queryset(self):
        return super().get_queryset().filter(your_filter)

, а затем добавьте его в свою модель BookAware с именем, отличным от «объектов»:

class BookAwareModel(models.Model):
    book = models.ForeignKey(Book)
    book_objects = BookAwareManager()

    class Meta:
        abstract = True

, позволяющий получить отфильтрованный набор запросов, например

MyNewModel.book_objects.all()

Опция 3

Поместите BookAwareManager, как во втором варианте, в качестве менеджера в ваш конкретный MyNewModel. Затем вы можете оставить имя менеджера в качестве «объектов» по ​​умолчанию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...