Allowed RemoveField operations to be optimized through.

This commit is contained in:
Simon Charette 2017-02-16 12:50:43 -05:00 committed by Tim Graham
parent 50b8c98a0f
commit 0025dd5eb4
3 changed files with 19 additions and 39 deletions

View File

@ -34,9 +34,7 @@ class FieldOperation(Operation):
return True return True
if self.field: if self.field:
return field_references_model(self.field, ModelTuple(app_label, name_lower)) return field_references_model(self.field, ModelTuple(app_label, name_lower))
# Refuse the temptation to guess. This operation could be performed on return False
# a field referencing the specified model.
return True
def references_field(self, model_name, name, app_label=None): def references_field(self, model_name, name, app_label=None):
model_name_lower = model_name.lower() model_name_lower = model_name.lower()
@ -60,10 +58,7 @@ class FieldOperation(Operation):
(getattr(remote_field, 'through_fields', None) is None or (getattr(remote_field, 'through_fields', None) is None or
name in remote_field.through_fields)): name in remote_field.through_fields)):
return True return True
return False return False
# Refuse the temptation to guess. This operation could be performed on
# a field referencing the specified model.
return True
def reduce(self, operation, in_between, app_label=None): def reduce(self, operation, in_between, app_label=None):
return ( return (

View File

@ -1925,11 +1925,9 @@ class AutodetectorTests(TestCase):
# Remove both the through model and ManyToMany # Remove both the through model and ManyToMany
# Right number/type of migrations? # Right number/type of migrations?
self.assertNumberMigrations(changes, "otherapp", 1) self.assertNumberMigrations(changes, "otherapp", 1)
self.assertOperationTypes(changes, "otherapp", 0, ["RemoveField", "RemoveField", "RemoveField", "DeleteModel"]) self.assertOperationTypes(changes, 'otherapp', 0, ['RemoveField', 'DeleteModel'])
self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="author", model_name='attribution') self.assertOperationAttributes(changes, 'otherapp', 0, 0, name='authors', model_name='book')
self.assertOperationAttributes(changes, 'otherapp', 0, 1, name="book", model_name='attribution') self.assertOperationAttributes(changes, 'otherapp', 0, 1, name='Attribution')
self.assertOperationAttributes(changes, 'otherapp', 0, 2, name="authors", model_name='book')
self.assertOperationAttributes(changes, 'otherapp', 0, 3, name='Attribution')
def test_many_to_many_removed_before_through_model_2(self): def test_many_to_many_removed_before_through_model_2(self):
""" """
@ -1944,14 +1942,10 @@ class AutodetectorTests(TestCase):
# Remove both the through model and ManyToMany # Remove both the through model and ManyToMany
# Right number/type of migrations? # Right number/type of migrations?
self.assertNumberMigrations(changes, "otherapp", 1) self.assertNumberMigrations(changes, "otherapp", 1)
self.assertOperationTypes(changes, "otherapp", 0, [ self.assertOperationTypes(changes, 'otherapp', 0, ['RemoveField', 'DeleteModel', 'DeleteModel'])
"RemoveField", "RemoveField", "RemoveField", "DeleteModel", "DeleteModel" self.assertOperationAttributes(changes, 'otherapp', 0, 0, name='authors', model_name='book')
]) self.assertOperationAttributes(changes, 'otherapp', 0, 1, name='Attribution')
self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="author", model_name='attribution') self.assertOperationAttributes(changes, 'otherapp', 0, 2, name='Book')
self.assertOperationAttributes(changes, 'otherapp', 0, 1, name="book", model_name='attribution')
self.assertOperationAttributes(changes, 'otherapp', 0, 2, name="authors", model_name='book')
self.assertOperationAttributes(changes, 'otherapp', 0, 3, name='Attribution')
self.assertOperationAttributes(changes, 'otherapp', 0, 4, name='Book')
def test_m2m_w_through_multistep_remove(self): def test_m2m_w_through_multistep_remove(self):
""" """
@ -1964,13 +1958,12 @@ class AutodetectorTests(TestCase):
# Right number/type of migrations? # Right number/type of migrations?
self.assertNumberMigrations(changes, "testapp", 1) self.assertNumberMigrations(changes, "testapp", 1)
self.assertOperationTypes(changes, "testapp", 0, [ self.assertOperationTypes(changes, "testapp", 0, [
"RemoveField", "RemoveField", "RemoveField", "DeleteModel", "DeleteModel" "RemoveField", "RemoveField", "DeleteModel", "DeleteModel"
]) ])
self.assertOperationAttributes(changes, "testapp", 0, 0, name="publishers", model_name='author') self.assertOperationAttributes(changes, "testapp", 0, 0, name="author", model_name='contract')
self.assertOperationAttributes(changes, "testapp", 0, 1, name="author", model_name='contract') self.assertOperationAttributes(changes, "testapp", 0, 1, name="publisher", model_name='contract')
self.assertOperationAttributes(changes, "testapp", 0, 2, name="publisher", model_name='contract') self.assertOperationAttributes(changes, "testapp", 0, 2, name="Author")
self.assertOperationAttributes(changes, "testapp", 0, 3, name="Author") self.assertOperationAttributes(changes, "testapp", 0, 3, name="Contract")
self.assertOperationAttributes(changes, "testapp", 0, 4, name="Contract")
def test_concrete_field_changed_to_many_to_many(self): def test_concrete_field_changed_to_many_to_many(self):
""" """
@ -2007,11 +2000,10 @@ class AutodetectorTests(TestCase):
changes = self.get_changes([self.author_with_publisher, self.publisher_with_author], []) changes = self.get_changes([self.author_with_publisher, self.publisher_with_author], [])
# Right number/type of migrations? # Right number/type of migrations?
self.assertNumberMigrations(changes, "testapp", 1) self.assertNumberMigrations(changes, "testapp", 1)
self.assertOperationTypes(changes, "testapp", 0, ["RemoveField", "RemoveField", "DeleteModel", "DeleteModel"]) self.assertOperationTypes(changes, "testapp", 0, ["RemoveField", "DeleteModel", "DeleteModel"])
self.assertOperationAttributes(changes, "testapp", 0, 0, name="publisher", model_name='author') self.assertOperationAttributes(changes, "testapp", 0, 0, name="author", model_name='publisher')
self.assertOperationAttributes(changes, "testapp", 0, 1, name="author", model_name='publisher') self.assertOperationAttributes(changes, "testapp", 0, 1, name="Author")
self.assertOperationAttributes(changes, "testapp", 0, 2, name="Author") self.assertOperationAttributes(changes, "testapp", 0, 2, name="Publisher")
self.assertOperationAttributes(changes, "testapp", 0, 3, name="Publisher")
def test_alter_model_options(self): def test_alter_model_options(self):
"""Changing a model's options should make a change.""" """Changing a model's options should make a change."""

View File

@ -2758,10 +2758,7 @@ class TestCreateModel(SimpleTestCase):
class FieldOperationTests(SimpleTestCase): class FieldOperationTests(SimpleTestCase):
def test_references_model(self): def test_references_model(self):
operation = FieldOperation('MoDel', 'field') operation = FieldOperation('MoDel', 'field', models.ForeignKey('Other', models.CASCADE))
# When missing a field declaration always assume it's referencing.
self.assertIs(operation.references_model('Whatever'), True)
operation.field = models.ForeignKey('Other', models.CASCADE)
# Model name match. # Model name match.
self.assertIs(operation.references_model('mOdEl'), True) self.assertIs(operation.references_model('mOdEl'), True)
# Referenced field. # Referenced field.
@ -2769,10 +2766,6 @@ class FieldOperationTests(SimpleTestCase):
# Doesn't reference. # Doesn't reference.
self.assertIs(operation.references_model('Whatever'), False) self.assertIs(operation.references_model('Whatever'), False)
def test_references_field_missing_field(self):
operation = FieldOperation('MoDel', 'field')
self.assertIs(operation.references_field('Whatever', 'missing'), True)
def test_references_field_by_name(self): def test_references_field_by_name(self):
operation = FieldOperation('MoDel', 'field', models.BooleanField(default=False)) operation = FieldOperation('MoDel', 'field', models.BooleanField(default=False))
self.assertIs(operation.references_field('model', 'field'), True) self.assertIs(operation.references_field('model', 'field'), True)