【问题标题】:Django filter through multiple fields in a many-to-many intermediary tableDjango过滤多对多中间表中的多个字段
【发布时间】:2025-12-20 15:00:11
【问题描述】:

我的 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)

但是,这将返回符合这两个假设的所有视频:

  • a) 包含该特定格式,并且
  • b) 包含状态为 10 的任何格式

我应该如何仅过滤状态代码为 10 的具有特定格式的人?

谢谢!

【问题讨论】:

  • 仅供参考,如果您想 OR 两个查询集,我相信您在查询集之间使用 |。不确定这对 OP 有多大帮助,但应该可以帮助到这里的其他人。

标签: django many-to-many django-orm


【解决方案1】:

您可以将过滤器链接在一起以形成“AND”结构。

格式为f且格式状态为10的视频

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

【讨论】:

【解决方案2】:

现在,我想过滤所有具有特定格式的视频,并且 该格式的状态码是 10(准备使用)。我怎样才能做到这一点? (假设 f 是格式)

您发布的代码完全符合您的要求:

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

这记录在the filter() documentation:

多个参数在底层 SQL 中通过 AND 连接 声明。

【讨论】:

    【解决方案3】:

    可能与 OP 无关,但可能与像我这样在寻找正确答案时发现此线程的其他人有关。

    Ludwik 说得对,但文档中解释所有这些以及如何排除的部分位于 queries documentation

    请注意,像 Chris 建议的那样,将过滤器拆分为两个 filter 调用会给您带来完全相反的结果:它将搜索具有媒体格式 f 且具有媒体格式的视频,不一定相同媒体格式,状态为 10。

    【讨论】: