6 votes

Existe-t-il un moyen d'éviter les jointures inutiles qui ne font que vérifier l'existence de l'id lorsque l'on utilise l'orm de Django ?

En exemple. Si j'ai un modèle Personne qui a un champ Mère, qui est une clé étrangère Ce qui suit m'interpelle :

p = Person.object.get(id=1)
if p.mother_id:
    print "I have a mother!"

Dans l'exemple ci-dessus, nous avons émis une requête. J'ai fait en sorte que Django ne récupère pas la mère en utilisant le champ _id au lieu de mother.id. Mais si je devais filtrer sur tous ceux qui n'ont pas de mère :

Person.objects.filter(mother=None)
Person.objects.filter(mother__id=None)
Person.objects.filter(mother__isnull=True)
Person.objects.filter(mother__id__isnull=True)

Toutes ces jointures sont inutiles dans la table liée et je ne peux pas référencer les colonnes _id, car ce ne sont pas des champs donc l'une ou l'autre des propositions suivantes échoue :

Person.objects.filter(mother_id__isnull=True)
Person.objects.filter(mother_id=None)

Existe-t-il un moyen pour moi de construire un querySet qui vérifie l'existence d'une valeur dans la colonne de la clé étrangère sans subir la jointure ?

Merci d'avance.

Edit (répondu) : Le mérite revient à Bernd, qui a commenté la réponse de Daniel, mais il s'avère que cette solution de contournement fonctionne parfaitement pour renvoyer les personnes sans mère, sans émettre de jointure inutile :

Person.objects.exclude(mother__isnull=False)

Modifier (plus de détails) :

Je dois également mentionner que j'ai constaté que ce comportement ne semble se manifester que lorsque la relation FK est annulable. Bizarre, mais vrai.

3voto

Daniel Roseman Points 199743

J'ai été surpris par cela - je pensais Person.object.filter(mother=None) fonctionnerait sans une jointure supplémentaire - mais après vérification, il s'avère que vous avez raison. En fait, cela a été enregistré comme un bug dans le système de suivi des tickets de Django.

Malheureusement, la personne qui l'a enregistré - et qui a (ré)écrit la majeure partie du code de la requête Django - ne contribue plus activement à Django, donc je ne sais pas quand le problème sera corrigé. Vous pouvez essayer l'un des correctifs de ce ticket et voir s'ils vous aident.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X