Django ManyToMany через индексацию моделей/таблиц
Для ManyToMany
отношений Django автоматически создаст корыто модели/таблицы.
Например, для:
class Magazine(models.Model):
pass
class Article(models.Model):
magazines = models.ManyToManyField('Magazine', related_name='articles')
будет Article.through
менеджер и модель. Связанная таблица будет иметь два отдельных индекса для каждого из столбцов.
Два вопроса:
- Как создать новый индекс для обоих столбцов? Я мог бы выполнить необработанный SQL-запрос, чтобы сделать это, но мне интересно, есть ли способ сделать что-то похожее на то, как
index_together
, который легко поддерживать и отслеживать. - Есть ли причина, по которой Django не добавляет автоматически индекс к обоим столбцам? В моем тесте я вручную создал индекс и увидел, что Postgres сильно увеличил его и производительность.
Если вы хотите внести изменения в промежуточную таблицу, используемую полем ManyToManyField, вы можете использовать аргумент through
для поля. Это позволит вам вручную определить промежуточную модель, в которую можно добавить многостолбцовый индекс. Обратите внимание, что index_together
был устаревшим в пользу indexes
.
Вот простой пример того, как выглядит добавление многоколоночного индекса в промежуточную таблицу, заданную вручную.
class Magazine(models.Model):
pass
class Article(models.Model):
magazines = models.ManyToManyField('Magazine', related_name='articles', through='MagazineArticle')
class MagazineArticle(models.Model):
magazine = models.ForeignKey('Magazine')
article = models.ForeignKey('Article')
class Meta:
indexes = [
models.Index(fields=["magazine", "article"])
[
Я не могу сказать, почему Django не создает этот индекс автоматически, но, по крайней мере, есть простой способ добавить его!
Документация:
Чтобы создать составной индекс по обоим столбцам:
Вы определяете свою собственную сквозную модель
class Magazine(models.Model):
pass
class Article(models.Model):
magazines = models.ManyToManyField('Magazine',
through='MagazineArticle',
related_name='articles')
class MagazineArticle(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
magazine = models.ForeignKey(Magazine, on_delete=models.CASCADE)
class Meta:
indexes = [
models.Index(fields=['article', 'magazine'])
]