Django: Найти все значения в отношении ManyToMany, где все элементы связанного набора соответствуют определенным критериям - PullRequest
3 голосов
/ 08 марта 2019

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

Сценарий: это словарь для совместной работы. Слово может иметь 0 или более определений. Определение может быть в нескольких состояниях: «завершено», «в процессе» или «прекращено». Я заинтересован в том, чтобы найти все слова, которые не имеют ни определений, либо только имеют "заброшенные" определения.

class DefinitionState(Enum):
    COMPLETE = 0
    IN_PROGRESS = 1
    ABANDONED = 2

class Definition(models.Model):
    text = models.TextField()
    status = models.IntegerField()

class Word(models.Model):
    text = models.CharField(length=60)
    definitions = models.ManyToManyField(Definition, related="words")

spam = Word.objects.create(text="spam")
eggs = Word.objects.create(text="eggs")
bacon = Word.objects.create(text="bacon")
lobster = Word.objects.create(text="lobster")

spam_d1 = Definition.objects.create(
    text="Processed meat", 
    status=DefinitionState.COMPLETE
)
spam_d2 = Definition.objects.create(
    text="Unwanted email",
    status=DefinitionState.ABANDONED
)
spam.definitions.add(spam_d1)
spam.definitions.add(spam_d2)

eggs_d = Definition.objects.create(
    text="Laid by chickens",
    status=DefinitionState.COMPLETE
)
eggs.definitions.add(eggs_d)

bacon_d = Definition.objects.create(
    text="Part of a pig",
    status=DefinitionState.ABANDONED
)
bacon.definitions.add(bacon_d)

Итак, у меня есть четыре слова:

  • spam, который имеет одно ПОЛНОЕ определение и одно ЗАБРОШЕННОЕ определение;
  • eggs, который имеет одно ПОЛНОЕ определение;
  • bacon, который имеет одно ЗАКРЫТОЕ определение;
  • lobster, который не имеет определений.

Я хочу написать запрос, который будет возвращать (bacon, lobster) (без определенного порядка).

Я могу написать запрос для возврата lobster:

Word.objects.annotate(Count("definitions")).filter(definitions__count=0)

и я могу определить, какие определения оставлены:

Definition.objects.filter(status=DefinitionState.ABANDONED)

но я не могу понять, как попросить слова, чьи определения все ЗАПРЕЩЕНЫ.

Большое спасибо заранее

1 Ответ

3 голосов
/ 08 марта 2019
Words.objects.exclude(definitions__status__in=[COMPLETE, IN_PROGRESS]) 
...