2011-05-10 11 views
18

Cómo hacer esto mediante consulta de objeto Django:Django consulta, donde en

SELECT * FROM test WHERE (test_id IN (SELECT test_id FROM test_subject_set)) AND (test_begin_time < '') AND (test_end_time > '') 

El modelo:

class Test(models.Model): 
    id = models.AutoField(primary_key=True) 
    user = models.ForeignKey(User) 
    groups = models.ManyToManyField(Group) 


class TestSubjectSet(models.Model): 
    id = models.AutoField(primary_key=True) 
    test = models.ForeignKey(Test) 
+1

por favor muestre su modelo django para esto. Y no estaría de más ser más descriptivo en lo que intentas lograr – gruntled

Respuesta

24

Dos QuerySets es documented manera de hacer esto. Sin embargo, será un hit de base de datos.

test_ids = Subject.objects.all() 
result = Test.objects.filter(test_id__in=test_ids).filter([some other filtering]) 
+0

Gracias por el enlace, lo intentaré. – kelvinfix

+0

El enlace está muerto. Utilice http://docs.djangoproject.com/en/1.9/ref/models/querysets/#in – neodelphi

+0

@neodelphi actualizado el enlace, gracias – DrTyrsa

6

DrTyrsa just about lo has lo.

test_ids = list(TestSubjectSet.objects.all().values_list('test_id', flat=True)) 
result = Test.objects.filter(id__in=test_ids, test_begin_time__lt='', test_end_time__gt='') 

La forma TYRSA estaba haciendo no le daría una lista de los ID de las pruebas de TestSubjectSet, sino que le dan un conjunto de consultas TestSubjectSet.

Además, me confundieron los campos test_begin_time y test_end_time, porque no los mencionó en sus modelos.

Actualización: Lista utilizada() en el conjunto de consultas, porque, de acuerdo con el enlace que DrTyrsa publicó, los DB "no optimizan muy bien los conjuntos de consultas anidados".

+0

Gracias Bryce Siedschlaw. ¿Hace algo diferente usando Values_list? – kelvinfix

+0

Lo siento, no entiendo tu pregunta. La función values_list devolverá los test_ids en cada registro TestSubjectSet. Por lo tanto, terminará con una lista de enteros relacionados con las claves de los registros de prueba. –

+0

@Bryce Siedschlaw Estás equivocado. Los Querysets son flojos y 'test_ids' se evaluará solo en la segunda línea, produciendo absolutamente la misma consulta SQL. Si desea realizar dos consultas SQL planas (en lugar de una anidada) debe escribir 'id__in = list (test_ids)', pero ambas variantes obtienen el mismo 'resultado'. – DrTyrsa