【问题标题】:Select record from a list of ids through M2M relations通过 M2M 关系从 id 列表中选择记录
【发布时间】:2015-06-02 14:25:45
【问题描述】:

首先,对不起我的英语不好,这个问题解释起来并不简单,所以我希望你能理解我。

我有以下两种型号:

class A(models.Model):
   code = models.CharField(unique=True, max_length=10)
   list_of_b = models.ManyToManyField('B')


class B(models.Model):
   code = models.CharField(unique=True, max_length=10)

我的目标是检索与给定 B id 列表完全匹配的 A 实例。

例如,假设我的数据库中有以下 A 的记录:

id: 1 - code: X - list_of_b: [1, 2, 4, 6]
id: 2 - code: Y - list_of_b: [2, 5, 6]
id: 3 - code: Z - list_of_b: [2, 3, 4, 5, 6]

使用[2, 5, 6] 作为给定列表,我应该检索记录 2 和 3,而不是 1。

我成功地检索到与此查询的 id 完全匹配的记录:

queryset = A.objects.prefetch_related('list_of_b')
queryset = queryset.annotate(nb=Count('list_of_b')).filter(nb=len(my_list))
for id in my_list:
    queryset = queryset.filter(list_of_b=id)

它适用于记录 2,但不适用于记录 3。

感谢您的帮助。如果不够清楚,请随时向我提问。 ;)

编辑:

还有一件事:my_list 也可能包含不必要的 ID。例如,[2, 5, 6, 7] 我应该检索记录 2 和 3。

【问题讨论】:

  • 查看我的答案here
  • 感谢您的回复。这是我在完全匹配的解决方案中所做的,但这里的重点是选择完全匹配记录以及更多,请查看我的示例以获取更多详细信息。
  • 哦,是的,我没注意到。但是@catavaran 是对的,因为filter(nb=len(my_list)),您没有获得记录 3
  • 在我的示例中添加新规则,仅删除元素计数上的过滤器对它不起作用。谢谢。 :)
  • 嗯,“新规则”有点混乱,那为什么我们不期望返回记录一呢?你能用普通的 SQL 写出你需要的东西吗?

标签: django orm m2m


【解决方案1】:

只需按计数删除过滤器:

queryset = A.objects.prefetch_related('list_of_b')
for id in my_list:
    queryset = queryset.filter(list_of_b=id)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2016-01-01
    相关资源
    最近更新 更多