2017-02-01 4 views
0

J'essaie d'utiliser la méthode .filter() de Django avec une liste d'objets enfants liés pour renvoyer l'ensemble d'objets parent qui contient tous les enregistrements enfants. Voir l'exemple ci-dessous.Django Filtre QuerySet sur la liste à l'aide de AND

L'utilisateur est l'objet parent et la couleur est l'objet enfant directement lié à l'utilisateur

  • User1 a des couleurs [rouge, bleu]
  • User2 a des couleurs [noir, violet, vert, bleu]
  • User3 a des couleurs [rouge, bleu, vert]
  • Utilisateur4 a des couleurs [rouge, bleu, vert, blanc]

    utilisateurs = users.filter (user_colors__color__in = couleurs)

couleurs est une liste définie par le POST. Par exemple. [rouge, bleu, vert]

Actuellement, les utilisateurs contiennent l'ensemble des utilisateurs qui ont [rouge, bleu, vert]. Pour l'exemple ci-dessus, j'obtiens actuellement User1, User2, User3 et User4 avec le code ci-dessus. C'est à dire. il utilise une recherche OU. Je veux retourner seulement les utilisateurs qui ont TOUTES les couleurs spécifiées. C'est à dire. utilisez une recherche AND. Pour l'exemple ci-dessus, je veux seulement obtenir User3 et User4. Quel est le meilleur moyen d'obtenir uniquement l'ensemble des enregistrements parents (utilisateurs) qui ont tous les enregistrements enfants (couleurs) demandés? Y at-il une méthode Django qui peut le faire facilement? Ou ai-je besoin d'une boucle qui filtre sur chaque couleur?

Merci!

+0

Je vous suggère de lire sur API Django queryset [ici] (https: //docs.djangoproject. com/fr/1.10/ref/models/querysets /) – hassan

+0

Veuillez poster vos modèles afin que nous puissions voir comment la relation est définie. – 2ps

Répondre

0

Une simple boucle suffira:

# list of color instances 
colors = [red, green, blue] 

for x in colors: 
    users = users.filter(user_colors__color=x) 

filtres successifs fonctionnera comme un ET

0

Disons que vous obtenez votre liste de couleurs d'ailleurs que je devine est le cas:

from django.db.models import Q 

# list of color instances 
colors = [red, green, blue] 

# create a list Q filters dynamically 
filter_by_this = [Q(user_colors__color=color) for color in colors] 

# filter using the filter as a list of arguments 
users = users.filter(*filter_by_this) 

Ce n'est pas testé, mais je crois que ce devrait être quelque chose comme ça.

Dans tous les cas, vous devriez lire sur le filtrage en utilisant Q objects.

+1

Vous pouvez simplement utiliser '__in' pour ou à la place de ceci. – 2ps

+0

OP a besoin de "&" non "ou" – mislavcimpersak