Как обрабатывается отношение «многие ко многим» в контексте БД и дает ли оно лучшую производительность?
С соединительной таблицей посередине, то есть с таблицей item_colors
. Но таблица содержит первичный ключ, как и любая модель в Django.
Если вы не укажете < strong>through=…
параметр [Django-doc], чтобы самостоятельно определить модель для соединительной таблицы, Django автоматически создаст такую модель. Затем эта модель имеет два ForeignKey
для двух моделей, которые она соединяет, как описано в представление базы данных документации:
За кулисами Django создает промежуточную таблицу соединений для представления отношения "многие ко многим". По умолчанию это имя таблицы создается с использованием имени поля «многие ко многим» и имени таблицы для модели, которая его содержит. Поскольку некоторые базы данных не поддерживают имена таблиц выше определенной длины, эти имена таблиц будут автоматически усечены, и будет использоваться хэш уникальности, например. author_books_9cdf
. Вы можете вручную указать имя таблицы соединений, используя параметр db_table
.
Но у таблицы таким образом есть первичный ключ. Это может быть полезно, если один и тот же объект встречается в отношении второй раз.
Вы можете получить доступ к сквозной модели в примере Article
-Publication
, например, с помощью:
Article.publications.through
Таким образом, вы можете самостоятельно определить сквозную модель, например, с помощью:
class Color(models.Model):
color = models.CharField(max_length=128)
class ClothItem(models.Model):
item_name = models.CharField(max_length=128)
colors = models.ManyToManyField(
Color,
related_name='cloth_items'
through='ClothItemColors'
)
class ClothItemColors(models.Model):
cloth_item = models.ForeignKey(ClothItem, on_delete=models.CASCADE)
color = models.ForeignKey(Color, on_delete=models.CASCADE)
class Meta:
db_table = 'item_colors'
constraints = [
models.UniqueConstraint(
fields=('cloth_item', 'color'),
name='unique_cloth_color'
)
]
часто для хранения дополнительной информации используется явная сквозная модель, например quantity
:
class ClothItemColors(models.Model):
cloth_item = models.ForeignKey(ClothItem, on_delete=models.CASCADE)
color = models.ForeignKey(Color, on_delete=models.CASCADE)
quantity = models.IntegerField(default=0)
# …
person
Willem Van Onsem
schedule
14.10.2020
ManyToManyField
создает промежуточную таблицу, но с первичным ключом. В Django каждая модель имеет первичный ключ. - person Willem Van Onsem   schedule 14.10.2020