chh*_*yal 20 django django-models django-migrations
我无法在文档或在线中找到对特定问题的引用.
我有很多关系.
class Books(models.Model):
name = models.CharField(max_length=100)
class Authors(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField(Books)
Run Code Online (Sandbox Code Playgroud)
这有迁移和数据.现在我需要使用through选项,以便在表中添加一个包含多对多关系的额外字段.
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)
Run Code Online (Sandbox Code Playgroud)
当我运行迁移时,django会为Authorship模型创建新的迁移.我尝试通过ordering在Authorship表中添加列并在表中更改books列来手动创建迁移文件,Authors但是我遇到了一些迁移问题.
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'),
),
]
Run Code Online (Sandbox Code Playgroud)
在尝试迁移时,KeyError: ('app_name', u'authorship')我认为还有其他因素会受到影响,从而导致错误.
我错过了什么?有没有其他方法可以解决这个问题?
小智 22
有一种方法可以在没有数据迁移的情况下添加"直通".我设法根据@MatthewWilkes的答案做到了.
因此,要将其转换为您的数据模型:
Authorship仅使用book和author字段创建模型.指定表名称以使用与您已有的自动生成的M2M表相同的名称.添加'through'参数.
class Authorship(models.Model):
book = models.ForeignKey(Books)
author = models.ForeignKey(Authors)
class Meta:
db_table = 'app_name_authors_books'
class Authors(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField(Books, through=Authorship)
Run Code Online (Sandbox Code Playgroud)生成迁移,但不要运行它.
编辑生成的迁移并将迁移操作包装到一个migrations. SeparateDatabaseAndState操作中,其中包含state_operations字段内的所有操作(database_operations左侧为空).你最终会得到这样的东西:
operations = [
migrations.SeparateDatabaseAndState(state_operations=[
migrations.CreateModel(
name='Authorship',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('book', models.ForeignKey(to='app_name.Books')),
],
options={
'db_table': 'app_name_authors_books',
},
),
migrations.AlterField(
model_name='authors',
name='books',
field=models.ManyToManyField(through='app_name.Authorship', to='app_name.Books'),
),
migrations.AddField(
model_name='authorship',
name='author',
field=models.ForeignKey( to='app_name.Author'),
),
])
]
Run Code Online (Sandbox Code Playgroud)您现在可以运行迁移并将额外ordering字段添加到M2M表.
编辑: 显然,对于自动M2M表,数据库中的列名称与模型定义的表格略有不同.(我使用的是Django 1.9.3.)
所描述的过程之后,我还与一个2字名称(手动改变字段的列名two_words=models.ForeignKey(...))从twowords_id到two_words_id.
chh*_*yal 11
看起来没有办法通过选项而无需进行数据迁移.所以不得不采用数据迁移方法,我从@pista329的答案中得到了一些想法,并使用以下步骤解决了这个问题.
创建Authorship模型
class Authorship(models.Model):
book = models.ForeignKey(Books)
author = models.ForeignKey(Authors)
ordering = models.PositiveIntegerField(default=1)
Run Code Online (Sandbox Code Playgroud)保持原始的ManyToManyField关系,但使用上面定义的模型通过模型添加另一个字段:
class Authors(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField(Books)
published_books = models.ManyToManyField(Books, through=Authorship, related_name='authors_lst') # different related name is needed.
Run Code Online (Sandbox Code Playgroud)添加数据迁移以将旧表中的所有数据复制到新Authorship表.
在此之后,可以删除模型上的books字段,Authors因为我们有新的字段命名published_books.
| 归档时间: |
|
| 查看次数: |
4426 次 |
| 最近记录: |