0

Lets say, for the example, that I have several models like below:

class People(models.Model):
    name = models.CharField()

class Job(models.Model):
    salary = models.IntegerField()
    employee = models.ForeignKey(People)        

    class Meta:
        abstract : True

class Artist(Job):
    # pass

class Vet(Job):
    # pass

class Doctor(Job):
    # pass
    class Meta:
        abstract : True

class Surgeon(Doctor):
    # pass

And now, let's say, I want to get all jobs worked by one people.

I would like to do something like

Mister_Jack = People.objects.get(pk=1)
jobs = Mister_Jack.job_set.all()

But it's not working as Job is abstract and the "job_set" relation doesn't exist. There is an "artist_set", an "surgeon_set" , etc. But I don't want to list all possible jobs.

What is the best way to do that ?

Note: the People & Job model is only an example to illustrate the pb.

Julien Greard
  • 969
  • 1
  • 12
  • 32
  • 1
    I found similar problem here: http://stackoverflow.com/questions/929029/how-do-i-access-the-child-classes-of-an-object-in-django-without-knowing-the-nam It is quite old (2009) but maybe it will help you. – Łukasz Staniszewski Feb 26 '14 at 11:07
  • very nice ! Yours keywords were better that mines for finding this good solution. thanks – Julien Greard Feb 26 '14 at 12:15

1 Answers1

2

You have to understand how abstract models work. The intended use case is to keep common fields for subclasses in one place. Abstract model classes don't have corresponding database table.

The implication is that Django cannot create any relation between People and Job, because such relation doesn't exist in reality. The other 3 subclassed models exist in the database, but they have no link between them therefore Django cannot do anything to help you out here. To get all possible jobs Django would have to make separate query for each table anyway.

You either need to change the Job model not to be abstract or join the models and use some type field to distinguish them. In my experience I have found model inheritance to be quite cumbersome and often decided to just use one bigger table at the expense of having some fields always be empty.

pajton
  • 15,828
  • 8
  • 54
  • 65
  • +1 for advice to avoid model inheritance. An alternative is generic relations. – Daniel Roseman Feb 26 '14 at 11:51
  • thanks for the advice and the best practice tip. I find that Django "Abstract Model" feature isn't complete without this kind of operations allowed. – Julien Greard Feb 26 '14 at 12:04
  • @DanielRoseman : how would you use generic relations in this example ? If the relation between People & Job was "one to one", I could use a generic relation from the People class, but it's one to many, and in this case, I don't see any alternative to having a foreignKey on the job classes – Julien Greard Feb 26 '14 at 12:06