Django excluyendo instancias específicas de queryset sin usar la búsqueda de campos


A veces tengo la necesidad de asegurarme de que algunas instancias están excluidas de un queryset.
Esta es la forma en que lo hago normalmente:

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

O, si tengo más de ellos:

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

Esto 'se siente' un poco torpe, así que lo intenté:

my_ideally_obtained_results = MyModel.objects.exclude(unwanted_instance)

Que no funciona. Pero leí aquí en SO que una subconsulta se puede usar como parámetro para excluir.
¿No tengo suerte? ¿Me falta alguna funcionalidad (revisé los documentos, pero no encontré ningún puntero útil)

Author: Community, 2010-06-13

3 answers

La forma en que ya lo estás haciendo es la mejor manera.

Si lo que buscas es una forma de hacer esto independiente del modelo, no olvides que puedes hacer query.exclude(pk=instance.pk).

Al igual que un lado, si el Dj de Django tuviera un mapeador de identidad (que no lo tiene en la actualidad), entonces podrías hacer algo como MyModel.objects.filter(<query>).all().remove(<instance>), pero no tienes suerte en ese sentido. La forma en que lo estás haciendo (o la anterior) es la mejor que tienes.

Oh, y también puedes hacer mucho mejor que eso in consulta con una lista comprensión: query.exclude(id__in=[o.id for o in <unwanted objects>])

 64
Author: obeattie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-13 13:59:07

La respuesta dada es perfecta y prueba esto que funciona bien para mí

Paso 1)

 from django.db.models import Q

Paso 2)

 MyModel.objects.filter(~Q(id__in=[o.id for o in <unwanted objects>]))
 5
Author: kartheek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-26 13:50:06

Puede poner sus elementos no deseados en una lista , y obtener todos los elementos excepto los de la lista de la siguiente manera:

MyModel.objects.exclude(id__in=[id1,id2,id3 ])
 0
Author: Seyyid Said,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-10 21:25:23