2010-01-13 17 views
7

tengo esta estructura de los objetos del modelo:Filtro de muchos a muchos relación en Django

Clase A:
b = models.ManyToManyField("B") 
Clase B:
c = models.ForeignKey("C") 
d = models.ForeignKey("D") 
Clase C:
d = models.ForeignKey("D") 

Esta es la consulta Estoy tratando de obtener:
Quiero obtener todos los objetos B del objeto A, luego en cada objeto B para realizar una comparación entre el objeto D y el objeto cd .

Sé que simplemente avance en la colección B con for loop y haga esta comparación. Pero se sumergió en la relación ManyToMany, entonces me di cuenta de que puedo hacer lo siguiente:

bObjects = A.objects.all().b 

q = bObjects.filter(c__d=None) 

Esto está trabajando, me da todos los objetos c con el campo None d. Pero cuando intento el siguiente:

q = bObjects.filter(c__d=d) 

Me da d no definido, pero d es un objeto como C en el objeto B.

Cuál puede ser el problema? Seré feliz si sugieres una forma más de hacer esta tarea. Por lo general, intento escribir mi consulta en una sola operación con muchos a muchos subobjetos y sin utilizar loops.

+1

todo esto es confuso abc podría no elegir mejores nombres: D? – maazza

Respuesta

6

q = bObjects.filter(c_d=d) //Give me d not defined. but d is an object like c in the object B.

Prueba esto:

from django.db.models import F 
q = bObjects.filter(c__d=F('d')) 

En cuanto a la pregunta de su comentario a continuación se puede tener 1 consulta SQL en lugar de 100 en aquellas formas:

1) si usted puede expresar su selección de un objetos en términos de una consulta (por ejemplo a.price < 10 y a.weight> 20) utiliza esta:

B.objects.filter(a__price__lt=10, a__weight__gt=20, c__d=F('d')) 

o esto:

B.objects.filter(a__in=A.objects.filter(price__lt=10, weight__gt=20), c_d=F('d')) 

2) si sólo tienes una lista de un pitón objetos, utilice la siguiente:

B.objects.filter(a__pk__in=[a.pk for a in your_a_list], c__d=F('d')) 
+0

Gracias asignar, Funciona. Una pregunta más: si tengo una lista de objetos del objeto principal A. ¿Puedo hacer la consulta que escribió con una línea y no repetir sobre la lista A y hacer lo mismo? Simplemente quiero guardar visitas a la ID de DB Tengo 100 de A, entonces tengo que hacer la consulta 100 veces. Gracias – Wasim

+0

Wasim, agregue .select_related ('a') al ten de su consulta –

+0

Muchas gracias, funciona. Nota: si escribo B.objects.filter (a__in = A.objects.filter (price__lt = 10, weight__gt = 20) .query, c_d = F ('d')). Lanza un error Error de SQL: el operando debe contener 1 columna (s). Miré el SQL generado, luego en lugar de .query lo reemplacé con .all y esto resolvió el problema. Gracias de nuevo. – Wasim

Cuestiones relacionadas