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)"])