Můžeme přímo filtrovat dokument pomocí ReferenceField's
pole v jednom dotazu?
Ne není možné přímo filtrovat dokument pomocí polí ReferenceField protože by to vyžadovalo spojení a mongodb nepodporuje spojení.
Podle dokumentů MongoDB na odkazy na databázi:
Z jiné stránky na oficiálních stránkách:
Takže v 1 dotazu nemůžeme oba filtrovat tasks s konkrétní hodnotou příznaku as daným user_id a task_id na UserTasks model.
Jak tedy provést filtrování?
Abychom mohli provést filtrování podle požadovaných podmínek, budeme muset provést 2 dotazy.
V prvním dotazu se pokusíme filtrovat Tasks model s daným task_id a flag . Poté ve 2. dotazu vyfiltrujeme UserTasks model s daným user_id a task načteno z prvního dotazu.
Příklad:
Řekněme, že máme user_id , task_id a musíme zkontrolovat, zda související úloha má flag hodnotu jako 0 .
První dotaz
Nejprve načteme my_task s daným task_id a flag jako 0 .
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
2. dotaz
Poté ve druhém dotazu musíte filtrovat podle UserTask model s daným user_id a my_task objekt.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
Druhý dotaz byste měli provést pouze v případě, že dostanete my_task objekt s daným task_id a flag hodnota. Také budete muset přidat zpracování chyb v případě, že neexistují žádné odpovídající objekty.
Co když jsme použili EmbeddedDocument pro Tasks model?
Řekněme, že jsme definovali naše Tasks dokument jako EmbeddedDocument a tasks pole v UserTasks modelovat jako EmbeddedDocumentField , pak k požadovanému filtrování bychom mohli udělat něco jako níže:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
Získání konkrétního my_task ze seznamu úkolů
Výše uvedený dotaz vrátí UserTask dokument, který bude obsahovat všechny tasks . Potom budeme muset provést nějakou iteraci, abychom získali požadovaný úkol.
K tomu můžeme provést pochopení seznamu pomocí enumerate() .Potom bude požadovaný index prvním prvkem vráceného seznamu s jedním prvkem.
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]