I agree about the roles solution, as depicted by Alex. What you have is not different subclasses of persons. You have different roles a person can have.
But I hear you say: "hey, the ninja can have a property "numberOfStars", while a singer can have a property "highestNote". Same as for the interface: a ninja can have the method throwStar() and disappear(), while a singer can have sing() and getWasted(), and the bass player can have goFunky() and slapPop()
What you have here is a case where your data model needs a very loose schema. So loose that, in fact, you have no schema at all. If the singer decides to take the bass and improvise a tune, that's fine. If he wants to act as a ninja, and you call throwStar, it will return an error, because he has no stars, but you could in principle, assign stars to a singer and make him throw stars.
What you are venturing in is the world of ontologies, rather than schemas. You have a resource, which is "something" and this something can be some type, have some properties, etc. Presence of some properties can infer the type, or presence of some type can infer other types. You cannot describe this information easily with the simple django data model. What you would need is a context-aware, inferenced graph store, such as AllegroGraph, or implement your hacked up solution using rdflib.