我在文档或网上找不到关于特定问题的参考资料。
我有一个现有的多对多关系。
class Books(models.Model):
name = models.CharField(max_length=100)
class Authors(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField(Books)
这有迁移和数据。现在我需要使用通过选项,以便在表中添加一个额外的字段持有多对多的关系。
class Authorship(models.Model):
book = models.ForeignKey(Books)
author = models.ForeignKey(Authors)
ordering = models.PositiveIntegerField(default=1)
class Authors(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField(Books, through=Authorship)
当我运行迁移时,django为Authorship
模型创建了新的迁移。我试图通过在Authorship
表中添加ordering
列并在Authors
表中更改books
列来手动创建迁移文件,但我遇到了一些迁移问题。
operations = [
migrations.AddField(
model_name='authorship',
name='ordering',
field=models.PositiveIntegerField(default=1),
),
migrations.AlterField(
model_name='authors',
name='books',
field=models.ManyToManyField(to='app_name.Books', through='app_name.Authorship'),
),
]
当试图迁移时,它给出了KeyError: ('app_name', u'authorship')
我敢打赌还有其他的东西受到影响,从而出现错误。
我遗漏了什么?有没有其他方法来处理这个问题?
3条答案
按热度按时间yk9xbfzb1#
有一种方法可以在不进行数据迁移的情况下添加“through”,我设法基于this @MatthewWilkes' answer做到了。
因此,将其转换为您的数据模型:
1.创建仅包含
book
和author
字段的Authorship
模型。指定表名以使用与您已有的自动生成的M2M表相同的名称。指定unique_together
属性以匹配自动生成的M2M表的功能(源)。添加'through'参数。1.生成迁移,但不要运行它。
1.编辑生成的迁移并将迁移操作 Package 到
migrations. SeparateDatabaseAndState
操作中,所有操作都在state_operations
字段中(database_operations
留空)。您将得到如下内容:1.现在可以运行迁移并将额外的
ordering
字段添加到M2M表中。**编辑:**显然,自动M2M表和模型定义的表在数据库中生成的列名略有不同(我使用的是Django 1.9.3)。
在完成所描述的过程之后,我还必须手动将具有两个单词名称(
two_words=models.ForeignKey(...)
)的字段的列名从twowords_id
更改为two_words_id
。3zwtqj6y2#
看起来没有办法使用通过选项而不必进行数据迁移。所以不得不求助于数据迁移方法,我从@pista329的回答中吸取了一些想法,并使用以下步骤解决了这个问题。
Authorship
模型重要提示:你必须使用一个不同的
related_name
到现有的ManyToManyField。如果你不这样做,Django可能会丢失原始字段中的数据。Authorship
表。在此之后,可以删除
Authors
模型上的books
字段,因为我们有一个名为published_books
的新字段。b1zrtrql3#
迁移有时会很麻烦。
如果你想通过through修改m2m字段,我建议你把修改后的字段
Authors.books
重命名为Authors.book
。当makemigrations
询问时,如果你把名字从books改为book?[yN]
,选择“N
”作为No。Django会删除books
并创建book
字段,而不是修改。如果您无论如何都要使用
books
,请将book
更改为books
,并使用y
重复迁移过程,以回答makemigrations关于重命名的问题。