为了举例,我有以下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中的某些对?即至少由一个给定的作者列表中的一个提供所有书籍?
I *想*写的查询如下所示:
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]
)
但这不起作用,因为所有的排列(Arthur Herbert,Frank Asimov,Isaac Clarke等等)都是允许的。但我不确定怎么说,基本上:
'选择所有 作者的书籍,同时满足这两件事。'
或者真的:
'选择所有拥有 作者的图书,其一对(last_name,first_name)位于此元组列表中。'
有没有一种干净的方式在django中进行搜索?
答案 0 :(得分:1)
我认为您可以使用q对象构建查询
Q(last_name=pair[0], first_name=pair[1]) | Q(last_name=pair2[0], first_name=pair2[1])
以上查询应该生成姓氏为clark且名字为arthur的书籍,或者last_name herbert和first_name frank。
关于如何动态执行此操作有很多答案:
How to dynamically compose an OR query filter in Django?
你可能不得不扭动查询并检查django生成的查询以验证它是你想要的
答案 1 :(得分:1)
好的我觉得这很有效:
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)
但如果你看到更好的东西,请仍然回答!
答案 2 :(得分:1)
你可以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)