Сначала не интуитивно понятно, но ответ прямо перед нами.
Book.objects.filter(author__id=1).filter(author__id=2)
Если вам нужно точное совпадение, вы можете дополнительно отфильтровать этот результат по тем элементам, которые имеют ровно 2 автора.
Book.objects.annotate(count=Count('author')).filter(author__id=1)\
.filter(author__id=13).filter(count=2)
Если вам нужны динамические точные совпадения, как насчет чего-то подобного?
def get_exact_match(model_class, m2m_field, ids):
query = model_class.objects.annotate(count=Count(m2m_field))\
.filter(count=len(ids))
for _id in ids:
query = query.filter(**{m2m_field: _id})
return query
matches = get_exact_match(MyModel, 'my_m2m_field', [1, 2, 3, 4])
# matches is still an unevaluated queryset, so you could run more filters
# without hitting the database.