How can I represent a many-to-many relationship with the same model?
I'll use the classic scenario of employees and managers: each employee
can have zero or more managers, and each manager can supervise zero or
more employees.
For example:
| Employee | Managers |
|==========|=============|
| Andy | <none> |
| Bob | Andy |
| Chance | Andy |
| Drew | Bob, Chance |
The first problem I ran into was that meta.ManyToManyField("self")
doesn't work. So, I went to option B, the intermediate table:
--- model ---
class Employee(meta.Model):
name = meta.CharField(maxlength=255)
# meta.ManyToMany("self") doesn't work
#managers = meta.ManyToManyField("self")
def __repr__(self):
return self.name
# Use an intermediate table
class EmployeeManager(meta.Model):
employee = meta.ForeignKey(Employee, related_name="employee")
manager = meta.ForeignKey(Employee, related_name="manager")
def __repr__(self):
return "Employee: %s; manager: %s" % (self.get_employee(),
self.get_manager())
--- /model ---
After populating the database accordingly, I ran the following simple
test:
--- snip ---
andy = employees.Employee(name="Andy")
andy.save()
bob = employees.Employee(name="Bob")
bob.save()
bob.add_manager(andy)
>>> Employee: Andy; manager: Bob
>>> I expected: Employee: Bob; manager: Andy
bob.get_employee_list()
>>> []
>>> What I expected
andy.get_manager_list()
>>> []
>>> What I expected
andy.get_employee_list()
>>> [Employee: Andy; manager: Bob]
>>> I expected: [Employee: Bob; manager: Andy]
--- /snip ---
The intermediate table approach is pretty close, except that the
employee/manager roles end up reversed.