迁移前从模型访问 Django 模型字段时出现问题
Problems accessing Django model fields from model before migration
我正在将字段 some_field
从 Model_A
移动到新的 Model_B
,具有 OneToOne 关系。在删除 Model_A
中的这个字段之前,我想将值从(历史)Model_A
复制到新创建的 Model_B
。问题是我无法在迁移时检索该字段,因为 Model_A
不再包含 some_field
.
这是我尝试 运行 我的自定义迁移时收到的错误消息:
AttributeError: 'Model_A' object has no attribute 'some_field'
更改前的型号:
class Model_A:
some_field = models.BooleanField(default=False)
some_other_field = models.BooleanField(default=False)
更改后的模型:
class Model_A:
some_other_field = models.BooleanField(default=False)
class Model_B:
model_a = models.OneToOneField(Model_A, related_name='extension')
some_field = models.BooleanField(default=False)
迁移:
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_initial'),
]
def forwards_func(apps, schema_editor):
# This is where I try to get the "historical" Model_A
Model_A = apps2.get_model("my_app", "Model_A")
# And this is where I intend to copy the some_field values
for model_A_instance in Model_A.objects.all():
b = Model_B(model_a=model_A_instance)
# b gets created correctly, but the following step fails
b.some_field = modelA_instance.some_field
b.save()
operations = [
migrations.CreateModel(
name='Model_B',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('some_field', models.BooleanField(default=False)),
('model_a', models.OneToOneField(related_name='extension', to='my_app.Model_A')),
],
options={
},
bases=(models.Model,),
),
migrations.RunPython(forwards_func),
migrations.RemoveField(
model_name='model_a',
name='some_field',
),
]
我非常清楚我必须以某种方式获得 Model_A
的 "historical" 表示(= 当前在数据库中的那个),但我认为那是 apps2.get_model("my_app", "Model_A")
部分用于.
关于如何完成这个的任何输入?或者我应该将迁移分成两部分,第一个创建 Model_B
+ 复制 some_field
值,第二个从 Model_A
中删除 some_field 字段?
是的,您需要具有 Model_A
的历史表现形式,并且很容易检索它。这就是 apps
传递给 RunPython
迁移调用的函数的目的,那么你为什么要在这里使用一些 apps2
insdead 应用程序?此外,您应该从与 Model_A
相同的 apps
实例中获取 Model_B
。您的迁移应如下所示:
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_initial'),
]
def forwards_func(apps, schema_editor):
# This is where I try to get the "historical" Model_A
# here is change - using apps passed into forwards_func by RunPython instead of apps2
Model_A = apps.get_model("my_app", "Model_A")
Model_B = apps.get_model("my_app", "Model_B")
# And this is where I intend to copy the some_field values
for model_A_instance in Model_A.objects.all():
b = Model_B(model_a=model_A_instance)
b.some_field = modelA_instance.some_field
b.save()
operations = [
migrations.CreateModel(
name='Model_B',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('some_field', models.BooleanField(default=False)),
('model_a', models.OneToOneField(related_name='extension', to='my_app.Model_A')),
],
options={
},
bases=(models.Model,),
),
migrations.RunPython(forwards_func),
migrations.RemoveField(
model_name='model_a',
name='some_field',
),
]
你为什么要使用 apps2
?它是什么?
我正在将字段 some_field
从 Model_A
移动到新的 Model_B
,具有 OneToOne 关系。在删除 Model_A
中的这个字段之前,我想将值从(历史)Model_A
复制到新创建的 Model_B
。问题是我无法在迁移时检索该字段,因为 Model_A
不再包含 some_field
.
这是我尝试 运行 我的自定义迁移时收到的错误消息:
AttributeError: 'Model_A' object has no attribute 'some_field'
更改前的型号:
class Model_A:
some_field = models.BooleanField(default=False)
some_other_field = models.BooleanField(default=False)
更改后的模型:
class Model_A:
some_other_field = models.BooleanField(default=False)
class Model_B:
model_a = models.OneToOneField(Model_A, related_name='extension')
some_field = models.BooleanField(default=False)
迁移:
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_initial'),
]
def forwards_func(apps, schema_editor):
# This is where I try to get the "historical" Model_A
Model_A = apps2.get_model("my_app", "Model_A")
# And this is where I intend to copy the some_field values
for model_A_instance in Model_A.objects.all():
b = Model_B(model_a=model_A_instance)
# b gets created correctly, but the following step fails
b.some_field = modelA_instance.some_field
b.save()
operations = [
migrations.CreateModel(
name='Model_B',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('some_field', models.BooleanField(default=False)),
('model_a', models.OneToOneField(related_name='extension', to='my_app.Model_A')),
],
options={
},
bases=(models.Model,),
),
migrations.RunPython(forwards_func),
migrations.RemoveField(
model_name='model_a',
name='some_field',
),
]
我非常清楚我必须以某种方式获得 Model_A
的 "historical" 表示(= 当前在数据库中的那个),但我认为那是 apps2.get_model("my_app", "Model_A")
部分用于.
关于如何完成这个的任何输入?或者我应该将迁移分成两部分,第一个创建 Model_B
+ 复制 some_field
值,第二个从 Model_A
中删除 some_field 字段?
是的,您需要具有 Model_A
的历史表现形式,并且很容易检索它。这就是 apps
传递给 RunPython
迁移调用的函数的目的,那么你为什么要在这里使用一些 apps2
insdead 应用程序?此外,您应该从与 Model_A
相同的 apps
实例中获取 Model_B
。您的迁移应如下所示:
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_initial'),
]
def forwards_func(apps, schema_editor):
# This is where I try to get the "historical" Model_A
# here is change - using apps passed into forwards_func by RunPython instead of apps2
Model_A = apps.get_model("my_app", "Model_A")
Model_B = apps.get_model("my_app", "Model_B")
# And this is where I intend to copy the some_field values
for model_A_instance in Model_A.objects.all():
b = Model_B(model_a=model_A_instance)
b.some_field = modelA_instance.some_field
b.save()
operations = [
migrations.CreateModel(
name='Model_B',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('some_field', models.BooleanField(default=False)),
('model_a', models.OneToOneField(related_name='extension', to='my_app.Model_A')),
],
options={
},
bases=(models.Model,),
),
migrations.RunPython(forwards_func),
migrations.RemoveField(
model_name='model_a',
name='some_field',
),
]
你为什么要使用 apps2
?它是什么?