Pouvons-nous filtrer directement sur un document avec le ReferenceField's
champs dans une seule requête ?
Non, il n'est pas possible de filtrer directement un document avec les champs de ReferenceField's
car cela nécessiterait des jointures et mongodb ne prend pas en charge les jointures.
Selon les documents MongoDB sur références de base de données :
Depuis une autre page sur le site officiel :
Donc, dans 1 requête, nous ne pouvons pas filtrer les tasks
à la fois avec une valeur d'indicateur particulière et avec le user_id
donné et task_id
sur les UserTasks
modèle.
Comment effectuer le filtrage alors ?
Pour effectuer le filtrage selon les conditions requises, nous devrons effectuer 2 requêtes.
Dans la première requête nous essaierons de filtrer les Tasks
modèle avec le task_id
donné et flag
. Ensuite, dans la 2ème requête, nous filtrerons les UserTasks
modèle avec le user_id
donné et la task
extrait de la première requête.
Exemple :
Disons que nous avons un user_id
, task_id
et nous devons vérifier si la tâche associée a flag
valeur 0
.
1ère requête
Nous allons d'abord récupérer le my_task
avec le task_id
donné et flag
comme 0
.
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
2e requête
Ensuite, dans la 2ème requête, vous devez filtrer sur UserTask
modèle avec le user_id
donné et my_task
objet.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
Vous ne devez effectuer la 2ème requête que si vous obtenez un my_task
objet avec le task_id
donné et flag
évaluer. De plus, vous devrez ajouter une gestion des erreurs au cas où il n'y aurait pas d'objets correspondants.
Et si nous avons utilisé EmbeddedDocument
pour les Tasks
modèle ?
Disons que nous avons défini nos tasks
document en tant que EmbeddedDocument
et les tasks
champ dans UserTasks
modèle en tant que EmbeddedDocumentField
, alors pour faire le filtrage souhaité, nous aurions pu faire quelque chose comme ci-dessous :
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
Obtenir le my_task
particulier de la liste des tâches
La requête ci-dessus renverra une UserTask
document qui contiendra toutes les tasks
. Nous devrons ensuite effectuer une sorte d'itération pour obtenir la tâche souhaitée.
Pour ce faire, nous pouvons effectuer une compréhension de liste en utilisant enumerate()
.Ensuite, l'index souhaité sera le 1er élément de la liste à 1 élément renvoyée.
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]