如何查询满足多个要求的单个实例的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.
根据您的回答,但未使用 reduce
和 operator
:
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)
为了举例,我有以下 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.
根据您的回答,但未使用 reduce
和 operator
:
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)