Django пользовательский менеджер моделей для производного класса - фильтрация по атрибуту базового класса

Я использую Django 3.2

У меня есть следующие модели:

class AuthoriseableApprovedManager(models.Manager):
    def get_queryset(self):
        return super(AuthoriseablePendingManager, self).get_queryset().filter(computed_status=AUTHORISATION_STATUS_APPROVED)



class Authorisable(models.Model):
    # various fields ...
    approved_objects = AuthoriseableApprovedManager()

class ApprovedPublishedArticlesManager(models.Manager):
    def get_queryset(self):
        return self.approved_objects.filter(is_published=True)
    
    
    
class Article(Authorisable, 
              # Other base classes
              ):
    
    # various fields
    # ....

    objects = models.Manager() # The default manager.
    
    approved_published_articles = ApprovedPublishedArticlesManager()
    
    
    class Meta:
        ordering = ('-created_at', )

У меня есть следующий код в файле views.py

class ArticleListView(ListView):
    model = Article

    def get_queryset(self):
        return self.model.approved_published_articles.all()  # <- Barfs here ...

Я получаю сообщение об ошибке:

У объекта 'ApprovedPublishedArticlesManager' нет атрибута 'approved_objects'

Что имеет смысл, поскольку ApprovedPublishedArticlesManager не вытекает из Authorisable.

Как мне создать пользовательский менеджер, который позволит мне фильтровать на основе свойств базового класса - должен ли мой пользовательский менеджер быть производным от models.Manager и соответствующего базового класса (Authorisable в данном случае)?

Проблема заключается в методе .get_queryset(…) вашего ApprovedPubhishedArtcilesManager. Вы можете получить доступ к модели с помощью:

class ApprovedPublishedArticlesManager(models.Manager):
    def get_queryset(self):
        return self.model.approved_objects.filter(is_published=True)

хотя, возможно, лучше наследоваться от AuthoriseableApprovedManager и использовать базовую реализацию метода .get_queryset(…). Это также более надежно, поскольку вам не нужно учитывать, под каким именем будет зарегистрирован менеджер.

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