django filtrage dynamique avec des objets q
J'essaie d'interroger une base de données basée sur des balises d'entrée utilisateur. Le nombre de balises peut être compris entre 0 et 5, donc j'ai besoin de créer la requête dynamiquement.
J'ai Donc une liste de balises, tag_list, et je veux interroger la base de données:
design_list = Design.objects.filter(Q(tags__tag__contains = "tag1") and Q(tags__tag__contains = "tag2") and etc. etc. )
Comment puis-je créer cette fonctionnalité?
3 réponses
Vous voudrez faire une boucle dans la tag_list et appliquer un filtre pour chacun d'eux.
tag_list = ['tag1', 'tag2', 'tag3']
base_qs = Design.objects.all()
for t in tag_list:
base_qs = base_qs.filter(tags__tag__contains=t)
Cela vous donnera des résultats correspondant à Toutes les balises, comme votre exemple l'indique avec and
. Si en fait vous avez besoin de or
à la place, vous aurez probablement besoin de q objects.
Edit: je pense avoir ce que vous cherchez maintenant.
tags = ['tag1', 'tag2', 'tag3']
q_objects = Q() # Create an empty Q object to start with
for t in tags:
q_objects |= Q(tags__tag__contains=t) # 'or' the Q objects together
designs = Design.objects.filter(q_objects)
J'ai testé cela et cela semble très bien fonctionner.
Edit 2: crédit à kezabelle dans # django sur Freenode pour l'initiale idée.
Il suffit de préparer une liste de balises d'abord, puis, requête comme ceci:
tags = ['tag1', 'tag2',...]
design_list = Design.objects.filter(tags__tag__contains__in = tags)
Vous pouvez utiliser cette façon:
my_dict = {'field_1': 1, 'field_2': 2, 'field_3': 3, ...} # Your dict with fields
or_condition = Q()
for key, value in my_dict.items():
or_condition.add(Q(**{key: value}), Q.OR)
query_set = MyModel.objects.filter(or_condition)
De cette façon, vous pouvez utiliser des noms de champs générés dynamiquement.
Vous pouvez également utiliser Q.AND
pour la condition AND
.