web-dev-qa-db-fra.com

Django excluant des instances spécifiques du jeu de requêtes sans utiliser la recherche de champ

J'ai parfois le besoin de m'assurer que certaines instances sont exclues d'un ensemble de requêtes.
Voici la façon dont je le fais habituellement:

unwanted_instance = MyModel.objects.get(pk=bad_luck_number)
uninteresting_stuff_happens()
my_results = MyModel.objects.exclude(id=unwanted_instance.id)

ou, si j'en ai plusieurs:

my_results = MyModel.objects.exclude(id_in=[uw_in1.id, uw_in2.id, uw_in3.id])

Cela "semble" un peu maladroit, alors j'ai essayé:

my_ideally_obtained_results = MyModel.objects.exclude(unwanted_instance)

Ce qui ne marche pas. Mais j'ai lu ici sur SO qu'une sous-requête peut être utilisée comme paramètre d'exclusion.
Suis-je malchanceux? Suis-je en manque de fonctionnalités (vérifié les documents, mais je n'ai trouvé aucun pointeur utile)

36
Agos

La façon dont vous le faites déjà est la meilleure façon.

Si c'est une façon indépendante du modèle de faire cela que vous recherchez, n'oubliez pas que vous pouvez faire query.exclude(pk=instance.pk).

Juste à part, si l'ORM de Django avait un mappeur d'identité (ce qui n'est pas le cas actuellement), alors vous seriez en mesure de faire quelque chose comme MyModel.objects.filter(<query>).all().remove(<instance>), mais vous êtes pas de chance à cet égard. La façon dont vous le faites (ou celle ci-dessus) est la meilleure que vous ayez.

Oh, et vous pouvez aussi faire beaucoup mieux que cette requête in avec une compréhension de la liste: query.exclude(id__in=[o.id for o in <unwanted objects>])

73
obeattie

La réponse donnée est parfaite et essayez cela qui fonctionne bien pour moi

étape 1)

 from Django.db.models import Q

étape 2)

 MyModel.objects.filter(~Q(id__in=[o.id for o in <unwanted objects>]))
6
kartheek

Vous pouvez mettre vos éléments indésirables dans une liste et récupérer tous les éléments sauf ceux de la liste comme ceci:

MyModel.objects.exclude(id__in=[id1,id2,id3 ])
1
Seyyid Said