1

I have model in Django. Project. It has foreign key to Organization model with related_name='projects'. So I can call my_org.projects.all(). But what if i'd like to call my_org.projects()? Let's check:

(Pdb++) org = Organization.objects.first()
(Pdb++) org.projects()
*** TypeError: __call__() missing 1 required keyword-only argument: 'manager'
(Pdb++) org.projects(None)
*** TypeError: __call__() takes 1 positional argument but 2 were given

That's really uncommon. So what causes this? Here's the code located in RelatedManager in Django:

        def __call__(self, *, manager):
            manager = getattr(self.model, manager)
            manager_class = create_reverse_many_to_one_manager(manager.__class__, rel)
            return manager_class(self.instance)

Can someone explain me how is this method constructed? As far as I know you can't place positional argument after an asterisk *args. But here we have (self, *, manager). Looks like programmer won't be able to pass manager ever!

Qback
  • 4,310
  • 3
  • 25
  • 38

1 Answers1

0

As @Abdul Niyas P M and @N Chauhan commented this is a trick to force calling this function using keyword arguments. Every positional argument will be consumed by asterisk, so the only way to pass manager is by using keyword-argument and will look like org.projects(manager=None). It's also nicely explained here.

Qback
  • 4,310
  • 3
  • 25
  • 38