Reputation: 8337
If I have a Django model:
class Person(models.Model):
name = models.CharField(max_length=45)
surname = models.CharField(max_length=45)
objects = PersonManager()
and its manager:
class PersonManager(models.Manager):
def create_person(self, fullname):
name, surname = fullname.split(" ", 1)
return self.create(name=name, surname=surname)
Extending that class:
class Actor(Person):
pass
doesn't have the same manager object, but the default one.
In [5]: Person.objects.create_person
Out[5]: <bound method PersonManager.create_person of <xxx.PersonManager object at 0x10297d190>>
In [6]: Actor.objects.create_person
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-468f84e48664> in <module>()
----> 1 Actor.objects.create_person
AttributeError: 'Manager' object has no attribute 'create_person'
Why is that and how can I propagate the manager to all subclasses?
Upvotes: 0
Views: 158
Reputation: 136
You can read more about this here: https://docs.djangoproject.com/en/dev/topics/db/managers/#custom-managers-and-model-inheritance
Basically managers are not inherited (from ordinary models). To get around this you can manually declare the manager in each model that should use the PersonManager. Or you can make Person an abstract model, that way all subclasses will inherit the PersonManager. Considering that you might want to add Directors, Producers or Technicians this might be the way to go. To do that you add the abstract attribute to Persons metaclass.
class Person(models.Model):
name = models.CharField(max_length=45)
surname = models.CharField(max_length=45)
objects = PersonManager()
class Meta:
abstract = True
Upvotes: 1