К примеру есть две модели Book and Scope.

Каждая Book может иметь много scope. На основании этих оценок методов Book.get_rating() определяет оценку самой Book.

Задача в том чтобы создать поле rating для модели Book, чтобы иметь возможность использовать его в админке для сортировки. Для этого используется аннотация вызывающаяся в методе models.QuerySet.

class BookQuerySet(models.QuerySet):
    """
    Queryset for books.
    """

    def books_with_rating(self):
        """Queryset with rating of each the book."""
       return self.annotation(rating=models.Avg('scope'))

Тогда метод Book.get_rating(), будет следующим

def get_rating(self):
        """Getting rating of book on based scopes."""

        return self.__class__.objects.books_with_rating().get(pk=self.pk).rating
get_rating.admin_order_field = 'rating'
get_rating.short_description = _('Rating')

Весь алгоритм работает и нет нарушения DRY, и в админке работает сортиорвка по полю rating для Book.

Проблема возникает когда появляется модель Writter и нужно для него определить среднюю оценку его книг и иметь возможность сортировки в админке. Понятно что вновь нужна аннотация.

Только как её сделать с модели Writter, ведь Book ещё не имеет поля rating для каждой книги автора:

то есть аннотация должа быть где-то такое

class WritterQuerySet(models.QuerySet):

    def wrritter_with_avg_rating_books(self):
       return self.annotation(avg_rating_by_books=models.Avg('rating'))

только вот в поля rating в Books автора ещё нет так как не вызван метод BookQuerySet.books_with_rating().

Нужно как-то решить эту проблему.

Если кто-то может предложить другое решению буду рад узнать.