The solution is a custom manager based on this blog post:
class PersonWithManagerManager(CommonManager):
""" Manager to get a query that adds the level and manager name
to the person record """
def get_query_set(self):
qs = super(PersonWithManagerManager, self).get_query_set()
cp_tab = qs.query.get_initial_alias()
# Join to the PCN table to find the position
pcn_tab = qs.query.join(
(
cp_tab,
PositionHierarchy._meta.db_table,
'pcn',
'pcn'
), promote=True)
# Find the manager's PCN
man_pcn_tab = qs.query.join(
(
pcn_tab,
PositionHierarchy._meta.db_table,
'reports_to_pcn',
'pcn'
), promote=True)
# Find the manager's person record
man_per_tab = qs.query.join(
(
man_pcn_tab,
'cart_person',
'pcn',
'pcn'
), promote=True)
return qs.extra(
select={
'level': '%s.level' % pcn_tab,
'manager_last_name': '%s.last_name' % man_per_tab,
'manager_first_name': '%s.first_name' % man_per_tab,
}
)
Now I can do print Person.extra_objects.filter(last_name='Tomblin').manager_last_name
and get my manager's last name. One thing I can't do yet is filter on them.