0
class ModelA(Model):
    pass

class ModelB(Model):
    modela = ForeignKey(ModelA, on_delete=CASCADE)

class ModelC(Model):
    modelb = ForeignKey(ModelB, on_delete_CASCADE)

In this case Django will automatically create a few additional managers for us. For example, if ma is an instance of ModelA, then we can write: ma.modelb_set.all(), and if mb is an instance of ModelB, then we can write: mb.modelc_set.all().

It would be convenient to be able to reference all ModelC instances related to ModelA. Of course, if ma is an instance of ModelA, we can always write: ModelC.objects.filter(modelb__modela=ma).distinct(). However, it would be more convenient if we could define a manager for ModelA that would allow us to execute the above query by simply writing: ma.modelc_set.all()

How to write such a manager for ModelA?

1 Answers1

1

This isn't really the job of a manager, but just a normal model method. Since you're looking for items that are related to a specific instance of ModelA, you can make a method on that model. If you really want, you can call it modelc_set and make it a property:

@property
def modelc_set(self):
    return ModelC.objects.filter(modelb__modela=self).distinct()
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • OK, thank you for your answer. In that case, however, why are Django’s default managers for reversing one-to-many relationships managers and not properties? –  Apr 10 '17 at 12:44
  • 2
    One thing you can’t do with properties: `prefetch_related('modelc_set')` –  Apr 10 '17 at 16:13