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(…)
. Это также более надежно, поскольку вам не нужно учитывать, под каким именем будет зарегистрирован менеджер.