Django фильтрует несколько полей в промежуточной таблице «многие ко многим» - PullRequest
12 голосов
/ 30 марта 2011

В моем проекте django есть следующие модели:

class Video(models.Model):
    media = models.ForeignKey(Media)

class Media(models.Model):
    title = models.CharField(max_length=255)
    formats = models.ManyToManyField(Format,through='MediaFormat',related_name='media',blank=True)

class Format(models.Model):
    title = models.CharField(max_length=50)

class MediaFormat(models.Model):
    status = models.IntegerField()
    format = models.ForeignKey(Format)
    media = models.ForeignKey(Media)

Теперь я хочу отфильтровать все видео, которые имеют определенный формат, И код состояния для этого формата - 10 (готов к использованию). Как я могу это сделать? (при условии, что f является форматом):

f = Format.objects.get(pk=3)

Мне хочется использовать:

Video.objects.filter(media__formats=f, media__mediaformat__status=10)

Но тогда, это вернуло бы все видео, которые соответствуют обоим из этих предположений:

  • а) содержит этот конкретный формат, а
  • б) содержать любой формат со статусом 10

Как я должен фильтровать только тех, кто имеет этот конкретный формат с кодом состояния 10?

спасибо!

Ответы [ 3 ]

12 голосов
/ 02 декабря 2013

Теперь я хочу отфильтровать все видео, которые имеют определенный формат, И код состояния для этого формата - 10 (готов к использованию).Как я могу это сделать?(при условии, что f - это формат)

Отправленный вами код будет делать именно то, что вы хотите:

Video.objects.filter(media__formats=f, media__mediaformat__status=10)

Это задокументировано в документации filter() :

Несколько параметров объединяются через AND в базовом операторе SQL.

9 голосов
/ 30 марта 2011

Вы можете объединить фильтры вместе для конструкции "И".

Видео, формат которых f И статус формата 10

Video.objects.filter(media__formats=f).filter(media__mediaformat__status=10)
2 голосов
/ 02 июля 2015

Вероятно, не относится к ОП, но может быть и для других, таких как я, которые нашли эту ветку при поиске правильного ответа.

Людвик понял это правильно, но раздел документации, который объясняет все этоКак и как делать исключения, содержится в документации запросов .

Обратите внимание, что разделение фильтра на два вызова filter, как предложил Крис, даст вам прямо противоположный результат:будет искать видео с мультимедийным форматом f и мультимедийным форматом, не обязательно того же формата, со статусом 10.

...