问题 试图在Django中创建一个带有外键列表的PostgreSQL字段


这是我正在尝试做的事情: 在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)数组的基本字段不能是相关字段。

关于如何击败的任何想法?


11745
2018-03-12 12:50


起源

你应该使用一个 ManyToMany 为此目的的领域。 - Selcuk


答案:


您无法创建外键数组。它不是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 领域

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()


13
2018-03-12 14:16



这是有道理的。谢谢!我只会使用值而不是外键。我有点担心性能,我需要这些相关键的唯一石灰是当我选择这个对象本身。 - Danil
我认为你应该仍然是一个多对多的关系。我设置了一个整数数组,你可能会遇到很多麻烦。尤其是数据完整性。我无法看到性能问题。 - Antoine Pinsard


你必须使用 ManyToManyFieldArrayField 不能与另一个模型相关。


0
2018-03-12 16:32