这是对这个问题的扩展:使用所需的ForeignKey引用在Django (1.8)应用程序之间移动模型
Nostalg.io的回答非常有效。但是,我仍然无法了解什么是“SeparateDatabaseAndState.状态操作”和“数据库操作”,以及使用数据库操作时实际发生了什么。
发布于 2022-01-10 19:01:08
这是一个有点棘手的话题,也没有足够清晰的解释,所以这是我的50美分。
这都是关于您的应用程序模型的状态。什么是州?假设您有一个带有模型MyModel和一些迁移的应用程序:
# app/migrations/
# 001.py
CreateModel(name='MyModel')
# 002.py
AddField(name='total', field=models.IntegerField)
# 003.py
RemoveField(name='total', field=models.IntegerField)当您调用manage.py makemigrations app时,Django将查看app/migrations/001.py...003.py中的所有更改,以获得模型中预期的内容-即模型的状态。因此,状态大概是迁移的综合结果。如果它与MyModel类中的app/models.py不同,则makemigrations会创建新的迁移,并进行相应的更改。就像如果MyModel类当前有total字段,而在上次迁移中它被移除一样,Django使用AddField()操作创建迁移。与人们通常认为的不同,makemigrations不看实际的数据库表。
正常的迁移操作会改变状态和数据库:CreateModel()告诉Django“嗨Django,这种迁移添加了新的表”并在数据库上执行"CREATE“。
当您需要对状态和数据库执行不同的操作时(或者您只需要修改其中的一个),就需要SeparateDatabaseAndState。
让我们看看姜戈博士中的例子,其中他们将现有的ManyToMany关系更改为“通过”模型。他们有具有M关系的模型作者和范本:
class Book(models.Model):
authors = models.ManyToManyField(Author)但是现在您希望有一个可选的全模型AuthorBook,其中包含一些额外的字段:
class AuthorBook(models.Model):
...
class Book(models.Model):
authors = models.ManyToManyField(Author, through=AuthorBook)但是您不需要新的表--您希望使用Django自动创建的现有core_book_authors表,并且希望其中包含数据。因此,您可以用SeparateDatabaseAndState操作创建一个带有database_operations和state_operations的迁移。
operations = [
migrations.SeparateDatabaseAndState(
database_operations=[
migrations.RunSQL(
sql='ALTER TABLE core_book_authors RENAME TO core_authorbook',
reverse_sql='ALTER TABLE core_authorbook RENAME TO core_book_authors',
),
],
state_operations=[
migrations.CreateModel(name='AuthorBook'),
]
),
]在database_operations中,它们根据新的模型名称重命名现有的M表。这是您实际需要对数据库做的唯一事情,除非同时向AuthorBook添加新字段。
带有state_operations的CreateModel()告诉Django:“这个迁移添加了新的表”(实际上它没有--正如我们从database_operations中知道的,它重命名了现有的表)。但是由于这个state_operations,我们的新模型进入了状态,Django知道这个模型是“创建”的,不会尝试在下一个makemigrations调用中创建它。
因此,在SeparateDatabaseAndState操作中,database_operations影响数据库而不是状态,state_operations影响状态而不是数据库。
https://stackoverflow.com/questions/61683766
复制相似问题