2011-12-19 82 views
23

¿cómo puedo tener una subconsulta en el queryset de django? por ejemplo si tengo:cómo subconsultar en queryset en django?

select name, age from person, employee where person.id = employee.id and 
employee.id in (select id from employee where employee.company = 'Private') 

esto es lo que he hecho todavía.

Person.objects.value('name', 'age') 
Employee.objects.filter(company='Private') 

pero no trabaja porque devuelve dos salidas ...

+2

Su ejemplo no es muy bueno. No necesita una subconsulta para esto: 'seleccionar nombre, edad de la persona, empleado donde person.id = employee.id y employee.company = 'Private'' –

Respuesta

11
ids = Employee.objects.filter(company='Private').values_list('id', flat=True) 
Person.objects.filter(id__in=ids).values('name', 'age') 
+14

Esto no es una subconsulta,' values_list' no devuelve un queryset. Esto hace dos consultas separadas. –

+1

No es una subconsulta, solo dos consultas. – Egg

+7

'values_list' devuelve un' ValuesQuerySet' y esas dos líneas realmente se traducirán en una sola consulta con una subconsulta. – BBT

31

como se ha mencionado por ypercube su caso de uso no requiere subconsulta.

pero de todos modos, ya que muchas personas entran a esta página para aprender cómo hacer una subconsulta aquí es cómo se hace.

employee_query = Employee.objects.filter(company='Private').only('id').all() 
Person.objects.value('name', 'age').filter(id__in=employee_query) 

Fuente: http://mattrobenolt.com/the-django-orm-and-subqueries/

+0

mencionado en los documentos: https://docs.djangoproject.com/en/1.9/ref/models/querysets/#in "también se puede usar un conjunto de preguntas para evaluar dinámicamente la lista de valores en lugar de proporcionar una lista de valores literales:" y "Este conjunto de consulta se evaluará como declaración de subselección". –

6

Puede crear subconsultas en Django usando un unevaluated queryset a filtrar su queryset principal. En su caso, se vería algo como esto:

employee_query = Employee.objects.filter(company='Private') 
people = Person.objects.filter(employee__in=employee_query) 

Estoy asumiendo que usted tiene una relación inversa Person-Employee llamado employee. Me pareció útil ver la consulta SQL generada por un conjunto de preguntas cuando estaba tratando de entender cómo funcionan los filtros.

print people.query 

Como han dicho otros, realmente no necesita una subconsulta para su ejemplo. Simplemente puede unirse a la tabla de empleados:

people2 = Person.objects.filter(employee__company='Private') 
Cuestiones relacionadas