นี่เป็นการทดสอบคร่าวๆดังนั้นอย่าลืมสำรอง 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
รูปแบบและเปลี่ยนชื่อ app_label ใน ProjectState 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
XXX1_dst_app_new
ย้ายMoveMe
จากไปsrc_app/models.py
dst_app/models.py
จากนั้นเรียกใช้:
python manage.py migrate
นั่นคือทั้งหมด!