Skip to content

Instantly share code, notes, and snippets.

@charettes
Created March 28, 2019 19:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charettes/913b05946b95f5a6862b4b273849c8af to your computer and use it in GitHub Desktop.
Save charettes/913b05946b95f5a6862b4b273849c8af to your computer and use it in GitHub Desktop.
import_model_operation.py
class ImportForeignModel(Operation):
"""Import a model from a foreign app to this one."""
def __init__(self, app_label, model_name):
self.app_label = app_label
self.model_name = model_name.lower()
def state_forwards(self, app_label, state):
imported_model_state = state.models[self.app_label, self.model_name].clone()
# Change the app label.
imported_model_state.app_label = app_label
# Default to pointing the db_table to the old one.
default_db_table = '{}_{}'.format(self.app_label, self.model_name.lower())
imported_model_state.options.setdefault('db_table', default_db_table)
# Assign the new model state
state.add_model(imported_model_state)
# Repoint all fields referencing the old model to the new one.
old_remote_model = '{}.{}'.format(self.app_label, self.model_name)
new_remote_model = '{}.{}'.format(app_label, self.model_name)
changed_models = []
for model_key, model_state in state.models.items():
model_changed = False
for index, (name, field) in enumerate(model_state.fields):
changed_field = None
remote_field = field.remote_field
if remote_field is None:
continue
if remote_field.to.lower() == old_remote_model:
changed_field = field.clone()
changed_field.remote_field.model = new_remote_model
through_model = getattr(remote_field, 'through', None)
if through_model and through_model.lower() == old_remote_model:
if changed_field is None:
changed_field = field.clone()
changed_field.remote_field.through = new_remote_model
if changed_field:
model_state.fields[index] = name, changed_field
model_changed = True
if model_changed:
changed_models.append(model_key)
# Reload and remove the old models.
state.reload_models(changed_models)
state.remove_model(self.app_label, self.model_name)
def database_forwards(self, app_label, schema_editor, from_state, to_state):
pass
def database_backwards(self, app_label, schema_editor, from_state, to_state):
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment