web-dev-qa-db-fra.com

Django filtre vs exclure

Y a-t-il une différence entre filtrer et exclure dans Django? Si j'ai

self.get_query_set().filter(modelField=x)

et je veux ajouter un autre critère, y a-t-il une différence significative entre les deux lignes de code suivantes?

self.get_query_set().filter(user__isnull=False, modelField=x)

self.get_query_set().filter(modelField=x).exclude(user__isnull=True)

est-on considéré comme une meilleure pratique ou sont-ils les mêmes en termes de fonction et de performance?

31
Enrico

Les deux sont évalués paresseusement, donc je m'attends à ce qu'ils fonctionnent de manière équivalente. Le SQL est probablement différent, mais sans réelle distinction.

22
Ned Batchelder

En général, l'exclusion est opposée au filtre. Dans ce cas, les deux exemples fonctionnent de la même manière.

Ici:

self.get_query_set().filter(user__isnull=False, modelField=x)

Vous sélectionnez les entrées dont l'utilisateur de champ n'est pas nul et modelField a la valeur x

Dans ce cas:

self.get_query_set().filter(modelField=x).exclude(user__isnull=True)

Commencez par sélectionner les entrées dont modelField a la valeur x (l'utilisateur est nul et l'utilisateur n'est pas nul), puis vous excluez les entrées dont le champ utilisateur est nul.

Je pense que dans ce cas, il serait préférable d'utiliser la première option, il semble plus propre. Mais les deux fonctionnent de la même façon.

19
Dominik Szopa

Cela dépend de ce que vous voulez réaliser. Avec les valeurs booléennes, il est facile de basculer entre .exclude() et .filter() mais qu'en est-il par exemple si vous voulez obtenir tous les articles sauf ceux de mars? Vous pouvez écrire la requête sous la forme

Posts.objects.exclude(date__month=3)

Avec .filter() ce serait (mais je ne sais pas si cela fonctionne réellement):

Posts.objects.filter(date__month__in=[1,2,4,5,6,7,8,9,10,11,12])

ou vous devrez utiliser un objet Q .

Comme le nom de la fonction le suggère déjà, .exclude() est utilisé pour exclure les jeux de données du jeu de résultats. Pour les valeurs booléennes, vous pouvez facilement inverser cela et utiliser .filter() à la place, mais pour d'autres valeurs, cela peut être plus délicat.

13
Felix Kling