У меня есть две модели в Django. Первый имеет иерархию того, какие рабочие функции (должности) подчиняются другим должностям, а второй - это люди и какие рабочие функции они выполняют.
class PositionHierarchy(model.Model):
pcn = models.CharField(max_length=50)
title = models.CharField(max_length=100)
level = models.CharField(max_length=25)
report_to = models.ForeignKey('PositionHierachy', null=True)
class Person(model.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
...
position = models.ForeignKey(PositionHierarchy)
Когда у меня есть запись человека, и я хочу найти менеджера человека, я должен сделать
manager = person.position.report_to.person_set.all()[0]
# Can't use .first() because we haven't upgraded to 1.6 yet
Если я получаю людей с QuerySet
, я могу присоединиться (и избежать повторного обращения к базе данных) с position и report_to, используя Person.objects.select_related('position', 'position__reports_to').filter(...)
, но есть ли способ избежать повторного обращения к базе данных для получения person_set? Я попытался добавить 'position__reports_to__person_set'
или просто position__reports_to__person
к select_related
, но это, похоже, не изменило запрос. Это то, для чего предназначено prefetch_related
?
Я хотел бы создать собственный менеджер, чтобы при выполнении запроса на получение записей Person я также получал их PositionHeirarchy и запись Person их менеджера без дополнительных обращений к базе данных. Это то, что у меня есть до сих пор:
class PersonWithManagerManager(models.Manager):
def get_query_set(self):
qs = super(PersonWithManagerManager, self).get_query_set()
return qs.select_related(
'position',
'position__reports_to',
).prefetch_related(
)
get_queryset()
, а неget_query_set
. - person Paolo   schedule 09.02.2018get_query_set
в Django 1.5. - person Paul Tomblin   schedule 09.02.2018