raw sql django

sql - raw - connection.cursor() django



Django en/no en consulta (5)

Estoy tratando de averiguar cómo escribir una consulta de estilo ''no en'' en django. Por ejemplo, la estructura de consulta en la que estoy pensando se vería así.

select table1.* from table1 where table1.id not in ( select table2.key_to_table1 from table2 where table2.id = some_parm )

¿Cómo se vería la sintaxis django asumiendo modelos llamados tabla1 y tabla2?


Puede escribir una búsqueda personalizada para las consultas de Django:

De la documentation : "Comencemos con una simple búsqueda personalizada. Escribiremos una búsqueda personalizada que funcione de forma opuesta a la exacta . Author.objects.filter (name__ne = ''Jack'') se traducirá al SQL: "author"."name" <> ''Jack'' Name "author"."name" <> ''Jack'' "

from django.db.models import Lookup class NotEqual(Lookup): lookup_name = ''ne'' def as_sql(self, compiler, connection): lhs, lhs_params = self.process_lhs(compiler, connection) rhs, rhs_params = self.process_rhs(compiler, connection) params = lhs_params + rhs_params return ''%s <> %s'' % (lhs, rhs), params


con estos modelos:

class table1(models.Model): field1 = models.CharField(max_length=10) # a dummy field class table2(models.Model): key_to_table1 = models.ForeignKey(table1)

deberías obtener lo que quieres usando:

table1.objects.exclude(table2=some_param)


table1.objects.exclude(id__in = table2.objects.filter(your_condition).values_list(''id'', flat=True))

La función de exclusión funciona como el operador Not que está solicitando. El atributo flat = True le dice a la consulta de la value_list que devuelva la lista de value_list como una lista de un nivel. Entonces ... al final está obteniendo una lista de IDs de la tabla 2, que va a usar para definir la condición en la table1 , que será denegada por la función de exclusión.


[o1 for o1 in table1.objects.all() if o1.id not in [o2.id for o2 in table2.objects.filter(id=some_parm)]]

O mejor

not_in_ids = [obj.id for obj in table2.objects.filter(id=some_parm)] selected_objects = [obj for obj in table1.objects.iterator() if obj.id not in not_in_ids]


table1.objects.extra(where=["table1.id NOT IN (SELECT table2.key_to_table1 FROM table2 WHERE table2.id = some_parm)"])