如何查询满足多个要求的单个实例的django m2m?

How to query django m2m for a single instance that satisfies multiple requirements?

为了举例,我有以下 Django 模型:

class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

class Book(models.Model):
    name = models.CharField(max_length=30)
    authors = models.ManyToManyField(Author)

(因为书籍通常有多个作者,而作者通常会写多本书)

现在假设我有一个元组形式的作者姓名列表:

author_list = [('clarke', 'arthur'), ('herbert', 'frank'), ('asimov', 'isaac')]

有没有一种方法可以查询 authors m2m 字段至少有一个 Author 实例满足

的所有书籍
author.last_name = pair[0]
author.first_name = pair[1]

author_list 中的某对? IE。获取至少由给定作者列表中的一位作者贡献的所有书籍?

我*想要*编写的查询如下所示:

Book.objects.filter(
    authors__first_name__in=[pair[1] for pair in author_list],
    authors__last_name__in=[pair[0] for pair in author_list]
)

但这行不通,因为所有的排列组合(亚瑟·赫伯特、弗兰克·阿西莫夫、艾萨克·克拉克等……)都是允许的。但我不确定怎么说,基本上:

'Select all books who have an author that satisfies these two things at once.'

或者真的:

'Select all books who have an author whose pair of (last_name, first_name) is in this list of tuples.'

在 django 中是否有一种干净的搜索方式?

我认为您可以使用 q 个对象构建查询

Q(last_name=pair[0], first_name=pair[1]) | Q(last_name=pair2[0], first_name=pair2[1])

上面的查询应该生成 get books with last name clark AND first name arthur OR last_name herbert and first_name frank.

有很多关于如何动态执行此操作的答案:

How to dynamically compose an OR query filter in Django?

您可能不得不摆弄查询并检查 django 生成的查询以验证它是否是您想要的

好的,我认为这可行:

query = []
for last_name, first_name in author_list:
    query.append(Q(authors__last_name=last_name, authors__first_name=first_name))
query = reduce(operator.or_, query)
Book.objects.filter(query)

但如果您看到更好的东西,请继续回答!

你可以build a query using Q objects.

根据您的回答,但未使用 reduceoperator

query = Q()
for last_name, first_name in author_list:
    Q |= Q(authors__last_name=last_name, authors__first_name=first_name)
Book.objects.filter(query)