让我们假设I have a polymorphic model,我想摆脱它。
class AnswerBase(models.Model):
question = models.ForeignKey(Question, related_name="answers")
response = models.ForeignKey(Response, related_name="answers")
class AnswerText(AnswerBase):
body = models.TextField(blank=True, null=True)
class AnswerInteger(AnswerBase):
body = models.IntegerField(blank=True, null=True)
当我想得到所有答案时,我永远无法访问“正文”,或者我需要尝试通过反复试验来获取子类的实例。
# Query set of answerBase, no access to body
AnswerBase.objects.all()
question = Question.objects.get(pk=1)
# Query set of answerBase, no access to body (even with django-polymorphic)
question.answers.all()
我不想因为性能而使用django-polymorphic,因为它似乎不适用于foreignKey关系,因为我不希望我的模型太复杂。所以我希望这种多态架构成为this simplified one:
class Answer(models.Model):
question = models.ForeignKey(Question, related_name="answers")
response = models.ForeignKey(Response, related_name="answers")
body = models.TextField(blank=True, null=True)
无法自动创建迁移,它会删除数据库中的所有旧答案。我已经阅读了Schema Editor documentation但似乎并没有将模型迁移到已存在的模型。所以我想创建自己的操作,将AnswerText
和AnswerInteger
保存为Answer
,然后删除AnswerText
和AnswerInteger
。我希望我不必直接编写SQL,但也许这是唯一的解决方案?我的迁移文件如下所示。我创建了一个名为MigrateAnswer的操作:
from myapp.migrations import MigrateAnswer
class Migration(migrations.Migration):
operations = [
migrations.RenameModel("AnswerBase", "Answer"),
migrations.AddField(
model_name='answer',
name='body',
field=models.TextField(blank=True, null=True),
),
MigrateAnswer("AnswerInteger"),
MigrateAnswer("AnswerText"),
migrations.DeleteModel(name='AnswerInteger',),
migrations.DeleteModel(name='AnswerText',),
]
所以我想在MigrateAnswer中做的是将旧模型(AnswerInteger
和AnswerText
)的值迁移到基类(现在命名为Answer
,previousely {{1 }})。这是我的操作类:
AnswerBase
所以我的问题是:是否可以使用“执行”(即:不编写SQL)来执行此操作。如果是这样,我应该在我的操作的for循环中做什么?
提前致谢!
答案 0 :(得分:2)
无需编写Operations类;数据迁移可以通过RunPython调用完成,如the docs所示。
在该函数中,您可以使用完全正常的模型实例方法;既然你知道要移动数据的字段,就不需要通过元查找来获取它们。
但是,您需要暂时以不同的名称调用新的body字段,因此它不会与子类上的旧字段冲突;您可以在最后重命名它并删除子类,因为该值将在基类中。
<section class="about" id="ABOUT">
<div class="about-sidebox l">demo left
</div>
<div class="about-mainbox">demo
</div>
<div class="about-sidebox r">demo right
</div>
</section>
答案 1 :(得分:0)
您可以为要进行这些修改的应用创建一个空迁移,并使用migrations.RunPython类来执行自定义python函数。