Когда вы создаете ManyToManyField
без указания промежуточной таблицы (используя through
), Django генерирует таблицу для вас. Эта таблица будет нуждаться только в pks обеих моделей, поэтому нет необходимости выбирать что-либо из других объектов, чтобы сохранить новые связи.
Для каждого из них будет создана новая строка, возможно, с использованием множества вставок, но необязательно много вызовов базы данных (например, возможен один запрос SQL с несколькими командами вставки). Вся информация, необходимая для этих созданий (pks ваших объектов), легко доступна, поэтому не нужно больше обращений к базе данных, чем необходимо.
Обновление: кажется, я ошибся. Просматривая источники (django / db / models / fields / related.py), я увидел, что он выполняет независимое создание для каждого объекта:
for obj_id in new_ids:
self.through._default_manager.using(db).create(**{
'%s_id' % source_field_name: self._pk_val,
'%s_id' % target_field_name: obj_id,
})
Перед этим он также проверяет, существовал ли какой-либо из предоставленных pks в базе данных (во избежание дублирования записей / нарушений ограничений уникальности):
vals = self.through._default_manager.using(db).values_list(target_field_name, flat=True)
vals = vals.filter(**{
source_field_name: self._pk_val,
'%s__in' % target_field_name: new_ids,
})
new_ids = new_ids - set(vals)
Эта проверка выполняется с помощью одного запроса ...