И так, некоторые время назад состоялось моё погружение в новый для джанго мир наследования моделей. Как и в моих домашних проектах и так и в рабочих. Исследованию подверглось мульти-табличное наследование. Среди достаточного количества удобных и полезных свойств наследования преподнесло несколько неожиданностей и даже ошибок, которые были обнаружены в механизме самой джанги.
Начнем с особенностей:
Кастомные менеджеры наследуются. Что вполне логично, если учесть, что менеджер это всего-лишь обычное поле класса, которое при наследовании переходит к наследнику. Но, что не очень очевидно на первый взгляд, так то, что он остается "прикрепленным" к модели предка и его использование с моделью наследника будет давать не совсем ожидаемы результат. Вот пример:
class Base( models.Model ): field1 = models.IntegerField() objects = models.Manager() my_custom_manager = MyManager() class Derived( Base ): field2 = models.IntegerField() #... Derived.my_custom_manager.filter( field2 = 777 )# Вот это не сработает # и ругнется на отсутсвие данного поля у Base модели, что есть правдаОтсюда вывод - переопределяйте свои менеджеры в моделях наследниках. Вот соответствующее обсуждение в джанго-девелоперс
Теперь немного копнем внутрь. Как вам известно список
fieldsу мета объекта модели содержит в себе поля данной модели. Так вот, у класса наследникаDerivedModel._meta.fieldsон содержит все поля, в том числе и поля всех родителей. Вот с этой конкретными ...