Наследование сложной модели - Django
Я думаю, что это немного сложно, по крайней мере для меня.:)
Итак, у меня есть 4 модели Лицо, Певец, Басист и Ниндзя.
Певец, басист и ниндзя наследуют от Лица.
Проблема заключается в том, что каждый Человек может быть любым из его подклассов.
например. Человек может быть певцом и ниндзя. Другой человек может быть басистом и ниндзя. Другим может быть все три.
Как мне организовать мои модели?
Помощь будет очень признательна!
Ответы
Ответ 1
Множественное наследование плохо работает с базами данных (и ваши модели Django в конце концов должны сопоставляться с базой данных), а наследование часто является плохим способом моделирования "ролей" (поскольку роли людей меняются). Я бы использовал Singer, Bassist и Ninja как "роли", не как подклассы Person и подключил их через внешние ключи:
class Singer(models.Model):
person = models.ForeignKey('Person')
# ...
class Person(models.Model):
# ...
Ответ 2
В принципе вы можете сделать что-то вроде следующего:
class Role(models.Model):
......
class Ninja(Role):
.......
class Person(models.Model):
roles = models.ManyToManyField(Role)
Но тогда вы столкнулись с проблемой, что Person.roles.objects.all() может предоставить вам только экземпляры Role. Таким образом, вам нужен метод для приведения каждого экземпляра Role в подходящий подкласс, такой как Ninja или Pirate. Вот ссылка на поток, который обсуждает эту проблему.
http://groups.google.com/group/django-users/browse_thread/thread/f4241bc16455f92d/7268c3f7bca6b046
Короче, Алекс и Стефано дали более полезные ответы, чем я.
Ответ 3
Я согласен с решением о ролях, как показано Алексом. У вас есть не разные подклассы людей. У вас есть разные роли, которые может иметь человек.
Но я слышу, как вы говорите: "Эй, ниндзя может иметь свойство" numberOfStars ", а певец может иметь свойство" highNote ". То же, что и для интерфейса: ниндзя может иметь метод throwStar() и исчезать(), в то время как певец может иметь sing() и getWasted(), а басист может иметь goFunky() и slapPop()
То, что у вас есть, - это случай, когда вашей модели данных нужна очень свободная схема. Настолько свободны, что на самом деле у вас нет схемы вообще. Если певец решает взять бас и импровизировать мелодию, это прекрасно. Если он хочет действовать как ниндзя, и вы вызываете throwStar, он вернет ошибку, потому что у него нет звезд, но вы могли бы в принципе назначить звезды певцу и заставить его бросать звезды.
То, чем вы занимаетесь, это мир онтологий, а не схемы. У вас есть ресурс, который является "чем-то", и это может быть какой-то тип, иметь некоторые свойства и т.д. Присутствие некоторых свойств может вывести тип, или наличие какого-либо типа может вывести другие типы. Вы не можете легко описать эту информацию с помощью простой модели данных django. Вам понадобится контекстно-зависимое хранилище графиков с индексом, такое как AllegroGraph, или реализуйте ваше взломанное решение с помощью rdflib.
Ответ 4
Вы можете сделать все свои профессии (Ninja, Bassist....) наследуемыми от Person в моделях, а затем использовать функцию isinstance в базовом коде, чтобы различают профессии Person.