J'essaie de comprendre comment écrire une requête de style "ne pas entrer" dans Django. Par exemple, la structure de requête à laquelle je pense ressemblerait à ceci.
select table1.*
from table1
where table1.id not in
(
select table2.key_to_table1
from table2
where table2.id = some_parm
)
À quoi ressemblerait la syntaxe Django en supposant des modèles appelés table1 et table2?
table1.objects.exclude(id__in=
table2.objects.filter(your_condition).values_list('id', flat=True))
La fonction exclude fonctionne comme l'opérateur Not
que vous demandiez. L'attribut flat = True
dit à table2
requête pour retourner le value_list
comme une liste à un niveau. Donc ... à la fin, vous obtenez une liste de IDs
de la table2, que vous allez utiliser pour définir la condition dans table1
, qui sera refusé par la fonction exclure.
avec ces modèles:
class table1(models.Model):
field1 = models.CharField(max_length=10) # a dummy field
class table2(models.Model):
key_to_table1 = models.ForeignKey(table1)
vous devriez obtenir ce que vous voulez en utilisant:
table1.objects.exclude(table2=some_param)
table1.objects.extra(where=["table1.id NOT IN (SELECT table2.key_to_table1 FROM table2 WHERE table2.id = some_parm)"])
Vous pouvez écrire une recherche personnalisée pour les Django requêtes:
À partir de la documentation : "Commençons par une simple recherche personnalisée. Nous écrirons une recherche personnalisée ne qui fonctionne en face de exact . Author.objects. filter (name__ne = 'Jack') se traduira en SQL: "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