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]