Salut,

Intéressante question.
J'ai cherché un peu et j'ai trouvé ça : https://groups.google.com/forum/?fromgroups=#!topic/django-users/X9TCSrBn57Y

Mais ça réponds partiellement à la question.

La bonne réponse c'est : Il n'y a pas de __exact__in

On ne peut pas faire de filter(tag__name__exact='xml', tag__name__exact='svg') par ce qu'il chercherait à trouver un élément dans les deux.

La meilleure solution AMHA c'est de faire un queryset par tag et de les merger.

>>> from marks.models import Mark
>>> queryset = Mark.objects.none()
>>> queryset += Mark.objects.filter(tag_name__exact='xml')
>>> queryset += Mark.objects.filter(tag_name__exact='svg')

Tu dois pouvoir mettre ça dans un manager pour que ce soit plus joli.

   from djqmixin import Manager, QMixin

   class MarkQMixin(QMixin):
        def exact_in(tags):
            queryset = self.none()
            for tag in tags:
                queryset += self.filter(tag_name__exact=tag)
            return queryset


Comme expliqué dans l'article ci-dessus c'est une mauvaise idée de chainer les .filter car ça va créer une jointure à chaque fois et avec un grand nombre de tag ça risque de tout casser.

Cordialement,

Rémy

Le 10/12/2012 14:24, Nicolas Steinmetz a écrit :
Hello,

Cherchant à rationnaliser différentes bases de codes, j'ai commencé à migrer une app de gestion de marks en Flask/MongoDB vers Django/Postgres. Comme il y a des tags aux marks, je ne me suis tourné vers django-taggit mais je n'aurais peut être pas du.

En effet, lors d'une recherche multi tags, il fait du OR au lieu de AND et sauf erreur, il ne sait pas le gérer. Avant que je désosse tout, je me suis dit que la sagesse populaire de django-fr pourrait me remettre sur le bon chemin.

Ex :

>>> from marks.models import Mark
>>> Mark.objects.filter(tag__name__in=['svg', 'xml']).count()
55
>>> Mark.objects.filter(tag__name__in=['svg']).count()
10
>>> Mark.objects.filter(tag__name__in=['xml']).count()
45
>>> Mark.objects.filter(tag__name__exact='xml').filter(tag__name__exact='svg').count()
1

Ce qui est pratique avec le tag__name__in=<list>, c'est que je peux justement lui passer une liste de 1 à n termes ; contrairement au dernier exemple qui demande à ce que je sache le nombre de termes à filtrer.

Est-ce que quelqu'un sait comment je peux faire cette fichue requête pour avoir un AND au lieu d'un OR ?

Une alternative à proposer ? J'espère ne surtout pas avoir à tomber dans du raw sql ; ce serait indigne de django pout un besoin aussi simple ;-)

Merci d'avance,
NIcolas

--
Nicolas Steinmetz
http://www.steinmetz.fr - http://nicolas.steinmetz.fr/


_______________________________________________
django mailing list
[email protected]
http://lists.afpy.org/mailman/listinfo/django

_______________________________________________
django mailing list
[email protected]
http://lists.afpy.org/mailman/listinfo/django

Répondre à