2017-02-21 75 views
0

Учитывая эти модели Django:Django объекты запросов со всеми связанными объектами встречи иного состоянием

class Job(models.Model): 
    pass 

class Task(models.Model): 
    job = models.ForeignKey('Job', related_name='tasks') 
    status = models.CharField(choices=TaskStatus.CHOICES, max_length=30) 
    dependencies = models.ManyToManyField("self", related_name="dependents", symmetrical=False) 

Я хочу, чтобы запросить все задачи со статусом ОЖИДАНИЕМ и всей зависимость, имеющей статус ЗАВЕРШЕНА для одного задания.

Я написал следующий запрос, но он возвращает задачи, имеющие хотя бы одну зависимость со статусом, который явно не нужен.

tasks_that_can_be_executed = Task.objects.filter(
    job__pk=job_id, 
    status=TaskStatus.PENDING, 
    dependencies__status=TaskStatus.COMPLETED 
) 

Любые предложения?

+0

где статус столбца? –

+0

@ PiyushS.Wanare добавил. Извините, я, должно быть, пропустил это, когда вы удалял несвязанный код для этого примера. – Korijn

+0

Почему все используют 'Q', я не знаю, что в основном это используется, когда нам нужно работать с условиями? и фильтр всегда работает с 'AND' –

ответ

3
from django.db.models import IntegerField, Case, When, Count, Q 

Task.objects.filter(
    job=job, 
    status=TaskStatus.PENDING, 
).annotate(
    not_completed_dependencies_count=Count(
     Case(When(~Q(dependencies__status=TaskStatus.COMPLETED), then=1), 
      output_field=IntegerField(), 
     ) 
    ) 
).filter(
    not_completed_dependencies_count__gt=0 
) 
0

Вы должны импортировать Q , а затем сделать что-то вроде:

from django.db.models import Q 

tasks_that_can_be_executed = Task.objects.filter(
    Q(job__pk=job_id) & Q(status=TaskStatus.PENDING) & Q(dependencies__status=TaskStatus.COMPLETED) 
) 
0

С Q от django.db.models вы можете сделать некоторые более сложные запросы. Если я понять вас правильно, вы хотите

from django.db.models import Q 

tasks_that_can_be_executed = Task.objects.filter(job__pk=job_id).filter(
     Q(status=TaskStatus.PENDING) | Q(dependencies__status=TaskStatus.COMPLETED) 
) 

Не уверен, что я правильно понял, что вы хотели, как результат, но в нынешней ситуации, вы получите все задачи из данного job_id, где status является PENDING вместе со всеми объектами, где dependencies__status является COMPLETED

+0

Почти! Мне нужны только задачи, в которых завершены все зависимости. – Korijn

+0

Извините, я пропустил ManyToMany. Я все еще ищу, но я не могу найти какое-то удовлетворение, но чтобы он был коротким и в одном запросе. – Nrzonline

+0

И я тоже. Мне удалось реализовать обходное решение, отфильтровывая потом ... но я бы скорее вложил его в запрос :) – Korijn