query - get object model django
select_related con llaves foráneas inversas (1)
Sí, para eso es prefetch_related()
. Se requerirá una consulta adicional, pero la idea es que obtendrá toda la información relacionada a la vez, en lugar de una vez por Person
.
En tu caso:
qs.select_related(''position__report_to'')
.prefetch_related(''position__report_to__person_set'')
debe requerir dos consultas, independientemente de la cantidad de Persons
en el conjunto de consulta original.
Compare este ejemplo de la documentation :
>>> Restaurant.objects.select_related(''best_pizza'')
.prefetch_related(''best_pizza__toppings'')
Tengo dos modelos en Django. El primero tiene la jerarquía de qué funciones de trabajo (cargos) informan a qué otras posiciones, y el segundo es personas y qué función de trabajo tienen.
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)
Cuando tengo un registro de persona y quiero encontrar el gerente de la persona, tengo que hacer
manager = person.position.report_to.person_set.all()[0]
# Can''t use .first() because we haven''t upgraded to 1.6 yet
Si QuerySet
personas con un QuerySet
, puedo unirme (y evitar un segundo viaje a la base de datos) con posición e informar_para usar Person.objects.select_related(''position'', ''position__reports_to'').filter(...)
, pero ¿hay alguna manera de evitar hacer otro viaje a la base de datos para obtener el person_set? Intenté agregar ''position__reports_to__person_set''
o simplemente position__reports_to__person
a select_related
, pero eso no parece cambiar la consulta. ¿Es esto para lo que prefetch_related
es?
Me gustaría crear un administrador personalizado para que cuando realice una consulta para obtener los registros de la persona, también obtenga su jerarquía de posición y la de su gerente sin más viajes de ida y vuelta a la base de datos. Esto es lo que tengo hasta ahora:
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(
)