이것은 대략적으로 테스트되었으므로 DB를 백업하는 것을 잊지 마십시오!
예를 들어, 두 개의 앱이 있습니다. src_app
및 dst_app
모델을 MoveMe
에서 src_app
로 이동하려고 합니다 dst_app
.
두 앱 모두에 대해 빈 마이그레이션을 만듭니다.
python manage.py makemigrations --empty src_app
python manage.py makemigrations --empty dst_app
의 새로운 마이그레이션이라는 것을, 가정하자 XXX1_src_app_new
하고 XXX1_dst_app_new
, previuos 위로 마이그레이션이 XXX0_src_app_old
와 XXX0_dst_app_old
.
MoveMe
모델의 테이블 이름을 바꾸고 ProjectState의 app_label 이름을로 바꾸는 작업을 추가하십시오 XXX1_dst_app_new
. XXX0_src_app_old
마이그레이션 에 대한 종속성을 추가하는 것을 잊지 마십시오 . 결과 XXX1_dst_app_new
마이그레이션은 다음과 같습니다.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
# this operations is almost the same as RenameModel
# https://github.com/django/django/blob/1.7/django/db/migrations/operations/models.py#L104
class MoveModelFromOtherApp(migrations.operations.base.Operation):
def __init__(self, name, old_app_label):
self.name = name
self.old_app_label = old_app_label
def state_forwards(self, app_label, state):
# Get all of the related objects we need to repoint
apps = state.render(skip_cache=True)
model = apps.get_model(self.old_app_label, self.name)
related_objects = model._meta.get_all_related_objects()
related_m2m_objects = model._meta.get_all_related_many_to_many_objects()
# Rename the model
state.models[app_label, self.name.lower()] = state.models.pop(
(self.old_app_label, self.name.lower())
)
state.models[app_label, self.name.lower()].app_label = app_label
for model_state in state.models.values():
try:
i = model_state.bases.index("%s.%s" % (self.old_app_label, self.name.lower()))
model_state.bases = model_state.bases[:i] + ("%s.%s" % (app_label, self.name.lower()),) + model_state.bases[i+1:]
except ValueError:
pass
# Repoint the FKs and M2Ms pointing to us
for related_object in (related_objects + related_m2m_objects):
# Use the new related key for self referential related objects.
if related_object.model == model:
related_key = (app_label, self.name.lower())
else:
related_key = (
related_object.model._meta.app_label,
related_object.model._meta.object_name.lower(),
)
new_fields = []
for name, field in state.models[related_key].fields:
if name == related_object.field.name:
field = field.clone()
field.rel.to = "%s.%s" % (app_label, self.name)
new_fields.append((name, field))
state.models[related_key].fields = new_fields
def database_forwards(self, app_label, schema_editor, from_state, to_state):
old_apps = from_state.render()
new_apps = to_state.render()
old_model = old_apps.get_model(self.old_app_label, self.name)
new_model = new_apps.get_model(app_label, self.name)
if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
# Move the main table
schema_editor.alter_db_table(
new_model,
old_model._meta.db_table,
new_model._meta.db_table,
)
# Alter the fields pointing to us
related_objects = old_model._meta.get_all_related_objects()
related_m2m_objects = old_model._meta.get_all_related_many_to_many_objects()
for related_object in (related_objects + related_m2m_objects):
if related_object.model == old_model:
model = new_model
related_key = (app_label, self.name.lower())
else:
model = related_object.model
related_key = (
related_object.model._meta.app_label,
related_object.model._meta.object_name.lower(),
)
to_field = new_apps.get_model(
*related_key
)._meta.get_field_by_name(related_object.field.name)[0]
schema_editor.alter_field(
model,
related_object.field,
to_field,
)
def database_backwards(self, app_label, schema_editor, from_state, to_state):
self.old_app_label, app_label = app_label, self.old_app_label
self.database_forwards(app_label, schema_editor, from_state, to_state)
app_label, self.old_app_label = self.old_app_label, app_label
def describe(self):
return "Move %s from %s" % (self.name, self.old_app_label)
class Migration(migrations.Migration):
dependencies = [
('dst_app', 'XXX0_dst_app_old'),
('src_app', 'XXX0_src_app_old'),
]
operations = [
MoveModelFromOtherApp('MoveMe', 'src_app'),
]
에 종속성을 추가 XXX1_dst_app_new
로 XXX1_src_app_new
. XXX1_src_app_new
이후 src_app
마이그레이션이 실행되도록 하는 데 필요한 no-op 마이그레이션입니다 XXX1_dst_app_new
.
MoveMe
에서 src_app/models.py
로 이동하십시오 dst_app/models.py
. 그런 다음 다음을 실행하십시오.
python manage.py migrate
그게 다야!