Подтвердить что ты не робот

Попытка сделать поле PostgreSQL со списком внешних ключей в Django

Вот что я пытаюсь сделать: Создайте модель в Django, которая представляет собой массив PostgreSQL (тип специфичного для базы данных), который содержит внешние ключи для другой модели.

class Books(models.Model):
authors = ArrayField(
    models.ForeignKey('my_app.Authors', default=None, null=True, blank=True),
    blank=True,
    default=list()
)

Когда я пытаюсь makemigrations, Django дает мне эту ошибку:

SystemCheckError: проверка системы выявила некоторые проблемы:

ОШИБКИ:

my_app.Books.authors: (postgres.E002) Базовое поле для массива не может быть связанным полем.

Любые идеи о том, как победить это?

4b9b3361

Ответ 1

Вы не можете создать массив внешних ключей. Это не ограничение Django, это ограничение "PostgreSQL".

Причина заключается в том, что внешний ключ не является типом, это ограничение для поля. Массив внешних ключей не вызывает никакого чувства.

Общий подход для достижения этого - использовать промежуточную таблицу, которая будет использоваться как связь между двумя другими:

Authors(id, name)
Books(id, title, pub_date)
BookAuthors(id, book_id, author_id)

В приведенном выше примере BookAuthors.book_id является внешним ключом для Books.id, а BookAuthors.author_id является внешним ключом Authors.id. Таким образом, таблица BookAuthors используется для сопоставления автора с книгой и наоборот.

Django реферат этой промежуточной таблицы с ManyToManyField fields:

class Authors(models.Model):
    name = models.CharField(...)

class Books(models.Model):
    title = models.CharField(...)
    pub_date = models.DateField(...)
    authors = models.ManyToManyField('my_app.Authors',
                                     related_name='authored_books')

За кулисами Django создаст промежуточную таблицу.

Затем вы можете получить всех авторов книги, используя book.authors.all(), или все книги, созданные автором, используя author.authored_books.all().

Ответ 2

Вы должны использовать ManyToManyField, ArrayField не могут быть связаны с другой моделью.