Skip to content

Commit

Permalink
merge proxy operations with their real versions
Browse files Browse the repository at this point in the history
  • Loading branch information
davidszotten committed May 11, 2014
1 parent 6e27124 commit 8008cc5
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 127 deletions.
26 changes: 15 additions & 11 deletions django/db/migrations/autodetector.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,21 @@ def _detect_changes(self):
if old_model_state.options.get('proxy') and not new_model_state.options.get('proxy'):
self.add_to_migration(
app_label,
operations.DeleteProxyModel(
operations.DeleteModel(
name=old_model_state.name,
orm_only=True,
)
)
old_model_keys.remove((app_label, model_name))
if not old_model_state.options.get('proxy') and new_model_state.options.get('proxy'):
self.add_to_migration(
app_label,
operations.CreateProxyModel(
operations.CreateModel(
name=new_model_state.name,
fields=[],
options=new_model_state.options,
bases=new_model_state.bases,
orm_only=True,
)
)
new_model_keys.remove((app_label, model_name))
Expand Down Expand Up @@ -138,14 +141,15 @@ def _rel_agnostic_fields_def(fields):
if model_fields_def == rem_model_fields_def:
if self.questioner.ask_rename_model(rem_model_state, model_state):
if model_state.options.get('proxy'):
rename_operation = operations.RenameProxyModel
orm_only = True
else:
rename_operation = operations.RenameModel
orm_only = False
self.add_to_migration(
app_label,
rename_operation(
operations.RenameModel(
old_name=rem_model_state.name,
new_name=model_state.name,
orm_only=orm_only,
)
)
renamed_models[app_label, model_name] = rem_model_name
Expand Down Expand Up @@ -230,10 +234,12 @@ def _rel_agnostic_fields_def(fields):
other_app_label, _ = pending_proxy_base[(app_label, model_name)]
self.add_to_migration(
app_label,
operations.CreateProxyModel(
operations.CreateModel(
name=model_state.name,
fields=[],
options=model_state.options,
bases=model_state.bases,
orm_only=True,
),
# If it's already been added in phase 2 put it in a new
# migration for safety.
Expand Down Expand Up @@ -553,20 +559,18 @@ def suggest_name(cls, ops):
but we put some effort in to the fallback name to avoid VCS conflicts
if we can.
"""
create_ops = (operations.CreateModel, operations.CreateProxyModel)
delete_ops = (operations.DeleteModel, operations.DeleteProxyModel)

if len(ops) == 1:
if isinstance(ops[0], create_ops):
if isinstance(ops[0], operations.CreateModel):
return ops[0].name.lower()
elif isinstance(ops[0], delete_ops):
elif isinstance(ops[0], operations.DeleteModel):
return "delete_%s" % ops[0].name.lower()
elif isinstance(ops[0], operations.AddField):
return "%s_%s" % (ops[0].model_name.lower(), ops[0].name.lower())
elif isinstance(ops[0], operations.RemoveField):
return "remove_%s_%s" % (ops[0].model_name.lower(), ops[0].name.lower())
elif len(ops) > 1:
if all(isinstance(o, create_ops) for o in ops):
if all(isinstance(o, operations.CreateModel) for o in ops):
return "_".join(sorted(o.name.lower() for o in ops))
return "auto_%s" % datetime.datetime.now().strftime("%Y%m%d_%H%M")

Expand Down
13 changes: 6 additions & 7 deletions django/db/migrations/operations/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from .models import (CreateModel, DeleteModel, CreateProxyModel,
DeleteProxyModel, AlterModelTable, AlterUniqueTogether, AlterIndexTogether,
RenameModel, RenameProxyModel)
from .models import (CreateModel, DeleteModel, AlterModelTable,
AlterUniqueTogether, AlterIndexTogether, RenameModel)
from .fields import AddField, RemoveField, AlterField, RenameField
from .special import SeparateDatabaseAndState, RunSQL, RunPython

__all__ = [
'CreateModel', 'DeleteModel', 'CreateProxyModel', 'DeleteProxyModel',
'AlterModelTable', 'AlterUniqueTogether', 'AlterIndexTogether',
'RenameModel', 'RenameProxyModel', 'AddField', 'RemoveField', 'AlterField',
'RenameField', 'SeparateDatabaseAndState', 'RunSQL', 'RunPython',
'CreateModel', 'DeleteModel', 'AlterModelTable', 'AlterUniqueTogether',
'RenameModel', 'AlterIndexTogether',
'AddField', 'RemoveField', 'AlterField', 'RenameField',
'SeparateDatabaseAndState', 'RunSQL', 'RunPython',
]
126 changes: 22 additions & 104 deletions django/db/migrations/operations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,29 @@ class CreateModel(Operation):
"""

serialization_expand_args = ['fields', 'options']
orm_only = False

def __init__(self, name, fields, options=None, bases=None):
def __init__(self, name, fields, options=None, bases=None, orm_only=False):
self.name = name
self.fields = fields
self.options = options or {}
self.bases = bases or (models.Model,)
self.orm_only = orm_only

def state_forwards(self, app_label, state):
state.models[app_label, self.name.lower()] = ModelState(app_label, self.name, self.fields, self.options, self.bases)

def database_forwards(self, app_label, schema_editor, from_state, to_state):
if self.orm_only:
return
apps = to_state.render()
model = apps.get_model(app_label, self.name)
if router.allow_migrate(schema_editor.connection.alias, model):
schema_editor.create_model(model)

def database_backwards(self, app_label, schema_editor, from_state, to_state):
if self.orm_only:
return
apps = from_state.render()
model = apps.get_model(app_label, self.name)
if router.allow_migrate(schema_editor.connection.alias, model):
Expand Down Expand Up @@ -73,19 +79,26 @@ class DeleteModel(Operation):
Drops a model's table.
"""

def __init__(self, name):
orm_only = False

def __init__(self, name, orm_only=False):
self.name = name
self.orm_only = orm_only

def state_forwards(self, app_label, state):
del state.models[app_label, self.name.lower()]

def database_forwards(self, app_label, schema_editor, from_state, to_state):
if self.orm_only:
return
apps = from_state.render()
model = apps.get_model(app_label, self.name)
if router.allow_migrate(schema_editor.connection.alias, model):
schema_editor.delete_model(model)

def database_backwards(self, app_label, schema_editor, from_state, to_state):
if self.orm_only:
return
apps = to_state.render()
model = apps.get_model(app_label, self.name)
if router.allow_migrate(schema_editor.connection.alias, model):
Expand All @@ -104,17 +117,21 @@ class RenameModel(Operation):
"""

reversible = False
orm_only = False

def __init__(self, old_name, new_name):
def __init__(self, old_name, new_name, orm_only=False):
self.old_name = old_name
self.new_name = new_name
self.orm_only = orm_only

def state_forwards(self, app_label, state):
state.models[app_label, self.new_name.lower()] = state.models[app_label, self.old_name.lower()]
state.models[app_label, self.new_name.lower()].name = self.new_name
del state.models[app_label, self.old_name.lower()]

def database_forwards(self, app_label, schema_editor, from_state, to_state):
if self.orm_only:
return
old_apps = from_state.render()
new_apps = to_state.render()
old_model = old_apps.get_model(app_label, self.old_name)
Expand All @@ -127,6 +144,8 @@ def database_forwards(self, app_label, schema_editor, from_state, to_state):
)

def database_backwards(self, app_label, schema_editor, from_state, to_state):
if self.orm_only:
return
old_apps = from_state.render()
new_apps = to_state.render()
old_model = old_apps.get_model(app_label, self.new_name)
Expand All @@ -148,107 +167,6 @@ def describe(self):
return "Rename model %s to %s" % (self.old_name, self.new_name)


class CreateProxyModel(Operation):
"""
Create model proxy (for the ORM, no db interactions required)
"""
serialization_expand_args = ['options']

def __init__(self, name, options=None, bases=None):
self.name = name
self.options = options or {}
self.bases = bases or (models.Model,)

def state_forwards(self, app_label, state):
state.models[app_label, self.name.lower()] = ModelState(app_label, self.name, [], self.options, self.bases)

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

def describe(self):
return "Create proxy model %s" % (self.name, )

def references_model(self, name, app_label=None):
strings_to_check = [self.name]
# Check we didn't inherit from the model
for base in self.bases:
if isinstance(base, six.string_types):
strings_to_check.append(base.split(".")[-1])
# Now go over all the strings and compare them
for string in strings_to_check:
if string.lower() == name.lower():
return True
return False

def __eq__(self, other):
return (
(self.__class__ == other.__class__) and
(self.name == other.name) and
(self.options == other.options) and
(self.bases == other.bases)
)

def __ne__(self, other):
return not (self == other)


class DeleteProxyModel(Operation):
"""
Delete model proxy (for the ORM, no db interactions required)
"""

def __init__(self, name):
self.name = name

def state_forwards(self, app_label, state):
del state.models[app_label, self.name.lower()]

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

def references_model(self, name, app_label=None):
return name.lower() == self.name.lower()

def describe(self):
return "Delete proxy model %s" % (self.name, )


class RenameProxyModel(Operation):
"""
Renames a proxy model (for the ORM, no db interactions required).
"""

def __init__(self, old_name, new_name):
self.old_name = old_name
self.new_name = new_name

def state_forwards(self, app_label, state):
state.models[app_label, self.new_name.lower()] = state.models[app_label, self.old_name.lower()]
state.models[app_label, self.new_name.lower()].name = self.new_name
del state.models[app_label, self.old_name.lower()]

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

def references_model(self, name, app_label=None):
return (
name.lower() == self.old_name.lower() or
name.lower() == self.new_name.lower()
)

def describe(self):
return "Rename proxy model %s to %s" % (self.old_name, self.new_name)


class AlterModelTable(Operation):
"""
Renames a model's table
Expand Down
17 changes: 12 additions & 5 deletions tests/migrations/test_autodetector.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,10 @@ def test_rename_proxy_model(self):
self.assertEqual(len(migration.operations), 1)
# Right action?
action = migration.operations[0]
self.assertEqual(action.__class__.__name__, "RenameProxyModel")
self.assertEqual(action.__class__.__name__, "RenameModel")
self.assertEqual(action.old_name, "AuthorProxy")
self.assertEqual(action.new_name, "WriterProxy")
self.assertTrue(action.orm_only)

def test_rename_model_with_renamed_rel_field(self):
"""
Expand Down Expand Up @@ -341,7 +342,8 @@ def test_proxy_dependency(self):
self.assertEqual(len(changes['otherapp']), 1)
migration = changes['otherapp'][0]
action = migration.operations[0]
self.assertEqual(action.__class__.__name__, "CreateProxyModel")
self.assertEqual(action.__class__.__name__, "CreateModel")
self.assertTrue(action.orm_only)
self.assertEqual(migration.dependencies, [("testapp", "__first__")])

def test_same_app_no_fk_dependency(self):
Expand Down Expand Up @@ -533,8 +535,9 @@ def test_add_proxy(self):
self.assertEqual(len(migration.operations), 1)
# Right actions?
action = migration.operations[0]
self.assertEqual(action.__class__.__name__, "CreateProxyModel")
self.assertEqual(action.__class__.__name__, "CreateModel")
self.assertEqual(action.name, "AuthorProxy")
self.assertTrue(action.orm_only)

def test_convert_to_proxy(self):
"Tests conversion of a non-proxy model to a proxy model"
Expand All @@ -549,10 +552,12 @@ def test_convert_to_proxy(self):
self.assertEqual(len(migration.operations), 2)
# Right actions?
action1, action2 = migration.operations
self.assertEqual(action1.__class__.__name__, "CreateProxyModel")
self.assertEqual(action1.__class__.__name__, "CreateModel")
self.assertEqual(action1.name, "AuthorProxy")
self.assertTrue(action1.orm_only)
self.assertEqual(action2.__class__.__name__, "DeleteModel")
self.assertEqual(action2.name, "AuthorProxy")
self.assertFalse(action2.orm_only)

def test_convert_from_proxy(self):
"Tests conversion of a non-proxy model to a proxy model"
Expand All @@ -567,10 +572,12 @@ def test_convert_from_proxy(self):
self.assertEqual(len(migration.operations), 2)
# Right actions?
action1, action2 = migration.operations
self.assertEqual(action1.__class__.__name__, "DeleteProxyModel")
self.assertEqual(action1.__class__.__name__, "DeleteModel")
self.assertEqual(action1.name, "AuthorProxy")
self.assertTrue(action1.orm_only)
self.assertEqual(action2.__class__.__name__, "CreateModel")
self.assertEqual(action2.name, "AuthorProxy")
self.assertFalse(action2.orm_only)
self.assertEqual(len(action2.fields), 1)

def test_fk_to_proxy_dependencies(self):
Expand Down

0 comments on commit 8008cc5

Please sign in to comment.