2014-06-17 2 views
2

J'essaie d'exclure tous les objets d'un ensemble de requêtes django ayant une clé étrangère dans un autre jeu de requête. Je ne réussis pas en utilisant exclude() cependant. S'il vous plaît aider.DJANGO: recherches de champs FK via QuerySet exclude()

Voici un extrait de la coquille de python:

>>> shipped = shipment_detail.objects.all() 
>>> shipped 
[<shipment_detail: 4>] 
>>> fo = fill_order.objects.exclude(product_order__in=shipped) 
>>> fo 
[<fill_order: 2>] 
>>> for x in shipped: 
... x.product_order.id 
... 
1 
>>> fo 
[<fill_order: 2>] 
>>> for x in fo: 
... x.product_order.id 
... 
1 

J'utilise django 1.7, python 2.7.7, 9.3 postgresql, sur debian sifflante.

MISE À JOUR: Réalisant que je peux voir le sql django utilise. C'est ici. De toute évidence pas ce que j'essaie d'atteindre. On dirait que j'ai besoin de dire explicitement à django que je veux faire référence à l'identifiant FK et non à l'identifiant d'enregistrement.

SELECT "box_inv_fill_order"."id", "box_inv_fill_order"."product_order_id", 
"box_ inv_fill_order" ."date" 
FROM "box_inv_fill_order" 
WHERE NOT ("box_inv_fill_order"."product_order_id" 
IN (SELECT "box_inv_shipment_detail"."id" FROM "box_inv_shipment_detail")) 
+1

Est-ce que 'fill_order.objects.exclude (product_order_id__in = [r.id pour r expédié])' faire une différence? Merci. – alecxe

+0

Thx @alecxe! Cela en combinaison avec regarder le sql réelle fait une solution assez simple et claire. Comme je référence un FK dans un QueryCenter 'embarqué', j'utilise' r.product_order pour r embarqué'. THX! –

+1

N'oubliez pas que vous pouvez utiliser '.values_list ('id', flat = True)' pour minimiser les ressources et l'optimiser. – dt0xff

Répondre

2

fo = fill_order.objects.exclude(product_order__in=shipped)

Produit:

SELECT "box_inv_fill_order"."id", "box_inv_fill_order"."product_order_id", 
"box_ inv_fill_order" ."date" 
FROM "box_inv_fill_order" 
WHERE NOT ("box_inv_fill_order"."product_order_id" 
IN (SELECT "box_inv_shipment_detail"."id" FROM "box_inv_shipment_detail")) 

Ce product_order_id contre shipment_detail_id compare. Pas ce que je l'intention!

Solution:

Utlizing suggestion @alecxe de .filter(...__in=[r.product_order for r in shipped]), crée une sql SELECT imbriqué comme paramètre IN.

SELECT "box_inv_fill_order"."id", "box_inv_fill_order"."product_order_id", "box_inv_fill_order"."date" 
FROM "box_inv_fill_order" 
WHERE NOT ("box_inv_fill_order"."product_order_id" 
IN (4)) 
Questions connexes