What's the difference between Custom model manager methods and QuerySet methods?

791 views Asked by At

I am trying to get my head around writing Custom managers. I found the online documentation a little sparse. Toying around myself with code, I discovered the following patterns:

Given the following model...

class QuestionQuerySet(models.QuerySet):
    def QS_first (self):
        return self.first()

class QuestionManager(models.Manager):
    def get_queryset(self):
        return QuestionQuerySet(self.model, using=self._db)

    def MN_first(self):
        return self.get_queryset().first()


class Question(models.Model):
    front = models.ForeignKey('Sentence', related_name='question_fronts')
    ....

I then get the following results...

Grammar.objects.filter(stage=1).question_set.MN_first()
<Question: [<Sentence: eve gideceğim>, <Sentence: I will go home>]>

Grammar.objects.filter(stage=1).question_set.QS_first()
AttributeError: 'RelatedManager' object has no attribute 'QS_first'

But

Question.objects.filter(grammar=1).QS_first()
<Question: [<Sentence: eve gideceğim>, <Sentence: I will go home>]>

Question.objects.filter(grammar=1).MN_first()
AttributeError: 'QuestionQuerySet' object has no attribute 'MN_first'

Why is it that the Manager methods are called when accessing the object through a DB relationship, but the Queryset methods are called when accessing the object directly? If I want the one method universally accessible (DRY), what would be the best solution?

1

There are 1 answers

0
Alasdair On BEST ANSWER

Have a look at the QuerySet.as_manager() method. It allows you to create a manager from a queryset, so that you don't need to duplicate code in a custom manager and queryset,