diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index 8535a98e735..e86e9c5f688 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -168,7 +168,7 @@ class MigrationAutodetector(object): and not old_field.rel.through._meta.auto_created): through_key = ( old_field.rel.through._meta.app_label, - old_field.rel.through._meta.object_name.lower(), + old_field.rel.through._meta.model_name, ) self.through_users[through_key] = (app_label, old_model_name, field_name) @@ -322,47 +322,47 @@ class MigrationAutodetector(object): if dependency[2] is None and dependency[3] is True: return ( isinstance(operation, operations.CreateModel) and - operation.name.lower() == dependency[1].lower() + operation.name_lower == dependency[1].lower() ) # Created field elif dependency[2] is not None and dependency[3] is True: return ( ( isinstance(operation, operations.CreateModel) and - operation.name.lower() == dependency[1].lower() and + operation.name_lower == dependency[1].lower() and any(dependency[2] == x for x, y in operation.fields) ) or ( isinstance(operation, operations.AddField) and - operation.model_name.lower() == dependency[1].lower() and - operation.name.lower() == dependency[2].lower() + operation.model_name_lower == dependency[1].lower() and + operation.name_lower == dependency[2].lower() ) ) # Removed field elif dependency[2] is not None and dependency[3] is False: return ( isinstance(operation, operations.RemoveField) and - operation.model_name.lower() == dependency[1].lower() and - operation.name.lower() == dependency[2].lower() + operation.model_name_lower == dependency[1].lower() and + operation.name_lower == dependency[2].lower() ) # Removed model elif dependency[2] is None and dependency[3] is False: return ( isinstance(operation, operations.DeleteModel) and - operation.name.lower() == dependency[1].lower() + operation.name_lower == dependency[1].lower() ) # Field being altered elif dependency[2] is not None and dependency[3] == "alter": return ( isinstance(operation, operations.AlterField) and - operation.model_name.lower() == dependency[1].lower() and - operation.name.lower() == dependency[2].lower() + operation.model_name_lower == dependency[1].lower() and + operation.name_lower == dependency[2].lower() ) # order_with_respect_to being unset for a field elif dependency[2] is not None and dependency[3] == "order_wrt_unset": return ( isinstance(operation, operations.AlterOrderWithRespectTo) and - operation.name.lower() == dependency[1].lower() and + operation.name_lower == dependency[1].lower() and (operation.order_with_respect_to or "").lower() != dependency[2].lower() ) # Field is removed and part of an index/unique_together @@ -370,7 +370,7 @@ class MigrationAutodetector(object): return ( isinstance(operation, (operations.AlterUniqueTogether, operations.AlterIndexTogether)) and - operation.name.lower() == dependency[1].lower() + operation.name_lower == dependency[1].lower() ) # Unknown dependency. Raise an error. else: @@ -696,7 +696,7 @@ class MigrationAutodetector(object): for name, field in sorted(related_fields.items()): dependencies.append((app_label, model_name, name, False)) # We're referenced in another field's through= - through_user = self.through_users.get((app_label, model_state.name.lower()), None) + through_user = self.through_users.get((app_label, model_state.name_lower), None) if through_user: dependencies.append((through_user[0], through_user[1], through_user[2], False)) # Finally, make the operation, deduping any dependencies @@ -842,7 +842,7 @@ class MigrationAutodetector(object): if hasattr(new_field, "rel") and getattr(new_field.rel, "to", None): rename_key = ( new_field.rel.to._meta.app_label, - new_field.rel.to._meta.object_name.lower(), + new_field.rel.to._meta.model_name, ) if rename_key in self.renamed_models: new_field.rel.to = old_field.rel.to @@ -1094,16 +1094,16 @@ class MigrationAutodetector(object): """ if len(ops) == 1: if isinstance(ops[0], operations.CreateModel): - return ops[0].name.lower() + return ops[0].name_lower elif isinstance(ops[0], operations.DeleteModel): - return "delete_%s" % ops[0].name.lower() + 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()) + 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()) + return "remove_%s_%s" % (ops[0].model_name_lower, ops[0].name_lower) elif len(ops) > 1: if all(isinstance(o, operations.CreateModel) for o in ops): - return "_".join(sorted(o.name.lower() 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") @classmethod diff --git a/django/db/migrations/operations/fields.py b/django/db/migrations/operations/fields.py index 6ce5e372969..ea9dffff1fd 100644 --- a/django/db/migrations/operations/fields.py +++ b/django/db/migrations/operations/fields.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals from django.db.models.fields import NOT_PROVIDED from django.utils import six +from django.utils.functional import cached_property from .base import Operation @@ -16,6 +17,14 @@ class AddField(Operation): self.field = field self.preserve_default = preserve_default + @cached_property + def name_lower(self): + return self.name.lower() + + @cached_property + def model_name_lower(self): + return self.model_name.lower() + def deconstruct(self): kwargs = { 'model_name': self.model_name, @@ -37,8 +46,8 @@ class AddField(Operation): field.default = NOT_PROVIDED else: field = self.field - state.models[app_label, self.model_name.lower()].fields.append((self.name, field)) - state.reload_model(app_label, self.model_name) + state.models[app_label, self.model_name_lower].fields.append((self.name, field)) + state.reload_model(app_label, self.model_name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): to_model = to_state.apps.get_model(app_label, self.model_name) @@ -63,10 +72,10 @@ class AddField(Operation): return "Add field %s to %s" % (self.name, self.model_name) def references_model(self, name, app_label=None): - return name.lower() == self.model_name.lower() + return name.lower() == self.model_name_lower def references_field(self, model_name, name, app_label=None): - return self.references_model(model_name) and name.lower() == self.name.lower() + return self.references_model(model_name) and name.lower() == self.name_lower class RemoveField(Operation): @@ -78,6 +87,14 @@ class RemoveField(Operation): self.model_name = model_name self.name = name + @cached_property + def name_lower(self): + return self.name.lower() + + @cached_property + def model_name_lower(self): + return self.model_name.lower() + def deconstruct(self): kwargs = { 'model_name': self.model_name, @@ -91,11 +108,11 @@ class RemoveField(Operation): def state_forwards(self, app_label, state): new_fields = [] - for name, instance in state.models[app_label, self.model_name.lower()].fields: + for name, instance in state.models[app_label, self.model_name_lower].fields: if name != self.name: new_fields.append((name, instance)) - state.models[app_label, self.model_name.lower()].fields = new_fields - state.reload_model(app_label, self.model_name) + state.models[app_label, self.model_name_lower].fields = new_fields + state.reload_model(app_label, self.model_name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): from_model = from_state.apps.get_model(app_label, self.model_name) @@ -112,10 +129,10 @@ class RemoveField(Operation): return "Remove field %s from %s" % (self.name, self.model_name) def references_model(self, name, app_label=None): - return name.lower() == self.model_name.lower() + return name.lower() == self.model_name_lower def references_field(self, model_name, name, app_label=None): - return self.references_model(model_name) and name.lower() == self.name.lower() + return self.references_model(model_name) and name.lower() == self.name_lower class AlterField(Operation): @@ -129,6 +146,14 @@ class AlterField(Operation): self.field = field self.preserve_default = preserve_default + @cached_property + def name_lower(self): + return self.name.lower() + + @cached_property + def model_name_lower(self): + return self.model_name.lower() + def deconstruct(self): kwargs = { 'model_name': self.model_name, @@ -149,10 +174,12 @@ class AlterField(Operation): field.default = NOT_PROVIDED else: field = self.field - state.models[app_label, self.model_name.lower()].fields = [ - (n, field if n == self.name else f) for n, f in state.models[app_label, self.model_name.lower()].fields + state.models[app_label, self.model_name_lower].fields = [ + (n, field if n == self.name else f) + for n, f in + state.models[app_label, self.model_name_lower].fields ] - state.reload_model(app_label, self.model_name) + state.reload_model(app_label, self.model_name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): to_model = to_state.apps.get_model(app_label, self.model_name) @@ -181,10 +208,10 @@ class AlterField(Operation): return "Alter field %s on %s" % (self.name, self.model_name) def references_model(self, name, app_label=None): - return name.lower() == self.model_name.lower() + return name.lower() == self.model_name_lower def references_field(self, model_name, name, app_label=None): - return self.references_model(model_name) and name.lower() == self.name.lower() + return self.references_model(model_name) and name.lower() == self.name_lower class RenameField(Operation): @@ -197,6 +224,18 @@ class RenameField(Operation): self.old_name = old_name self.new_name = new_name + @cached_property + def old_name_lower(self): + return self.old_name.lower() + + @cached_property + def new_name_lower(self): + return self.new_name.lower() + + @cached_property + def model_name_lower(self): + return self.model_name.lower() + def deconstruct(self): kwargs = { 'model_name': self.model_name, @@ -211,19 +250,19 @@ class RenameField(Operation): def state_forwards(self, app_label, state): # Rename the field - state.models[app_label, self.model_name.lower()].fields = [ + state.models[app_label, self.model_name_lower].fields = [ (self.new_name if n == self.old_name else n, f) - for n, f in state.models[app_label, self.model_name.lower()].fields + for n, f in state.models[app_label, self.model_name_lower].fields ] # Fix index/unique_together to refer to the new field - options = state.models[app_label, self.model_name.lower()].options + options = state.models[app_label, self.model_name_lower].options for option in ('index_together', 'unique_together'): if option in options: options[option] = [ [self.new_name if n == self.old_name else n for n in together] for together in options[option] ] - state.reload_model(app_label, self.model_name) + state.reload_model(app_label, self.model_name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): to_model = to_state.apps.get_model(app_label, self.model_name) @@ -249,10 +288,10 @@ class RenameField(Operation): return "Rename field %s on %s to %s" % (self.old_name, self.model_name, self.new_name) def references_model(self, name, app_label=None): - return name.lower() == self.model_name.lower() + return name.lower() == self.model_name_lower def references_field(self, model_name, name, app_label=None): return self.references_model(model_name) and ( - name.lower() == self.old_name.lower() or - name.lower() == self.new_name.lower() + name.lower() == self.old_name_lower or + name.lower() == self.new_name_lower ) diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py index 6dd66ae4541..773c70526f9 100644 --- a/django/db/migrations/operations/models.py +++ b/django/db/migrations/operations/models.py @@ -5,6 +5,7 @@ from django.db.models.options import normalize_together from django.db.migrations.state import ModelState from django.db.migrations.operations.base import Operation from django.utils import six +from django.utils.functional import cached_property class CreateModel(Operation): @@ -21,6 +22,10 @@ class CreateModel(Operation): self.bases = bases or (models.Model,) self.managers = managers or [] + @cached_property + def name_lower(self): + return self.name.lower() + def deconstruct(self): kwargs = { 'name': self.name, @@ -87,6 +92,10 @@ class DeleteModel(Operation): def __init__(self, name): self.name = name + @cached_property + def name_lower(self): + return self.name.lower() + def deconstruct(self): kwargs = { 'name': self.name, @@ -98,7 +107,7 @@ class DeleteModel(Operation): ) def state_forwards(self, app_label, state): - state.remove_model(app_label, self.name) + state.remove_model(app_label, self.name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): model = from_state.apps.get_model(app_label, self.name) @@ -111,7 +120,7 @@ class DeleteModel(Operation): schema_editor.create_model(model) def references_model(self, name, app_label=None): - return name.lower() == self.name.lower() + return name.lower() == self.name_lower def describe(self): return "Delete model %s" % (self.name, ) @@ -126,6 +135,14 @@ class RenameModel(Operation): self.old_name = old_name self.new_name = new_name + @cached_property + def old_name_lower(self): + return self.old_name.lower() + + @cached_property + def new_name_lower(self): + return self.new_name.lower() + def deconstruct(self): kwargs = { 'old_name': self.old_name, @@ -147,18 +164,18 @@ class RenameModel(Operation): if f.auto_created and not f.concrete and not (f.hidden or f.many_to_many) ) # Rename the model - 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 - state.remove_model(app_label, self.old_name) + 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 + state.remove_model(app_label, self.old_name_lower) # Repoint the FKs and M2Ms pointing to us for related_object in all_related_objects: # Use the new related key for self referential related objects. if related_object.related_model == model: - related_key = (app_label, self.new_name.lower()) + related_key = (app_label, self.new_name_lower) else: related_key = ( related_object.related_model._meta.app_label, - related_object.related_model._meta.object_name.lower(), + related_object.related_model._meta.model_name, ) new_fields = [] for name, field in state.models[related_key].fields: @@ -168,7 +185,7 @@ class RenameModel(Operation): new_fields.append((name, field)) state.models[related_key].fields = new_fields state.reload_model(*related_key) - state.reload_model(app_label, self.new_name) + state.reload_model(app_label, self.new_name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): new_model = to_state.apps.get_model(app_label, self.new_name) @@ -184,12 +201,12 @@ class RenameModel(Operation): for related_object in old_model._meta.related_objects: if related_object.related_model == old_model: model = new_model - related_key = (app_label, self.new_name.lower()) + related_key = (app_label, self.new_name_lower) else: model = related_object.related_model related_key = ( related_object.related_model._meta.app_label, - related_object.related_model._meta.object_name.lower(), + related_object.related_model._meta.model_name, ) to_field = to_state.apps.get_model( *related_key @@ -201,14 +218,18 @@ class RenameModel(Operation): ) def database_backwards(self, app_label, schema_editor, from_state, to_state): + self.new_name_lower, self.old_name_lower = self.old_name_lower, self.new_name_lower self.new_name, self.old_name = self.old_name, self.new_name + self.database_forwards(app_label, schema_editor, from_state, to_state) + + self.new_name_lower, self.old_name_lower = self.old_name_lower, self.new_name_lower self.new_name, self.old_name = self.old_name, self.new_name def references_model(self, name, app_label=None): return ( - name.lower() == self.old_name.lower() or - name.lower() == self.new_name.lower() + name.lower() == self.old_name_lower or + name.lower() == self.new_name_lower ) def describe(self): @@ -224,6 +245,10 @@ class AlterModelTable(Operation): self.name = name self.table = table + @cached_property + def name_lower(self): + return self.name.lower() + def deconstruct(self): kwargs = { 'name': self.name, @@ -236,8 +261,8 @@ class AlterModelTable(Operation): ) def state_forwards(self, app_label, state): - state.models[app_label, self.name.lower()].options["db_table"] = self.table - state.reload_model(app_label, self.name) + state.models[app_label, self.name_lower].options["db_table"] = self.table + state.reload_model(app_label, self.name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): new_model = to_state.apps.get_model(app_label, self.name) @@ -261,7 +286,7 @@ class AlterModelTable(Operation): return self.database_forwards(app_label, schema_editor, from_state, to_state) def references_model(self, name, app_label=None): - return name.lower() == self.name.lower() + return name.lower() == self.name_lower def describe(self): return "Rename table for %s to %s" % (self.name, self.table) @@ -279,6 +304,10 @@ class AlterUniqueTogether(Operation): unique_together = normalize_together(unique_together) self.unique_together = set(tuple(cons) for cons in unique_together) + @cached_property + def name_lower(self): + return self.name.lower() + def deconstruct(self): kwargs = { 'name': self.name, @@ -291,9 +320,9 @@ class AlterUniqueTogether(Operation): ) def state_forwards(self, app_label, state): - model_state = state.models[app_label, self.name.lower()] + model_state = state.models[app_label, self.name_lower] model_state.options[self.option_name] = self.unique_together - state.reload_model(app_label, self.name) + state.reload_model(app_label, self.name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): new_model = to_state.apps.get_model(app_label, self.name) @@ -309,7 +338,7 @@ class AlterUniqueTogether(Operation): return self.database_forwards(app_label, schema_editor, from_state, to_state) def references_model(self, name, app_label=None): - return name.lower() == self.name.lower() + return name.lower() == self.name_lower def describe(self): return "Alter %s for %s (%s constraint(s))" % (self.option_name, self.name, len(self.unique_together or '')) @@ -327,6 +356,10 @@ class AlterIndexTogether(Operation): index_together = normalize_together(index_together) self.index_together = set(tuple(cons) for cons in index_together) + @cached_property + def name_lower(self): + return self.name.lower() + def deconstruct(self): kwargs = { 'name': self.name, @@ -339,9 +372,9 @@ class AlterIndexTogether(Operation): ) def state_forwards(self, app_label, state): - model_state = state.models[app_label, self.name.lower()] + model_state = state.models[app_label, self.name_lower] model_state.options[self.option_name] = self.index_together - state.reload_model(app_label, self.name) + state.reload_model(app_label, self.name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): new_model = to_state.apps.get_model(app_label, self.name) @@ -357,7 +390,7 @@ class AlterIndexTogether(Operation): return self.database_forwards(app_label, schema_editor, from_state, to_state) def references_model(self, name, app_label=None): - return name.lower() == self.name.lower() + return name.lower() == self.name_lower def describe(self): return "Alter %s for %s (%s constraint(s))" % (self.option_name, self.name, len(self.index_together or '')) @@ -372,6 +405,10 @@ class AlterOrderWithRespectTo(Operation): self.name = name self.order_with_respect_to = order_with_respect_to + @cached_property + def name_lower(self): + return self.name.lower() + def deconstruct(self): kwargs = { 'name': self.name, @@ -384,9 +421,9 @@ class AlterOrderWithRespectTo(Operation): ) def state_forwards(self, app_label, state): - model_state = state.models[app_label, self.name.lower()] + model_state = state.models[app_label, self.name_lower] model_state.options['order_with_respect_to'] = self.order_with_respect_to - state.reload_model(app_label, self.name) + state.reload_model(app_label, self.name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): to_model = to_state.apps.get_model(app_label, self.name) @@ -410,7 +447,7 @@ class AlterOrderWithRespectTo(Operation): self.database_forwards(app_label, schema_editor, from_state, to_state) def references_model(self, name, app_label=None): - return name.lower() == self.name.lower() + return name.lower() == self.name_lower def describe(self): return "Set order_with_respect_to on %s to %s" % (self.name, self.order_with_respect_to) @@ -439,6 +476,10 @@ class AlterModelOptions(Operation): self.name = name self.options = options + @cached_property + def name_lower(self): + return self.name.lower() + def deconstruct(self): kwargs = { 'name': self.name, @@ -451,13 +492,13 @@ class AlterModelOptions(Operation): ) def state_forwards(self, app_label, state): - model_state = state.models[app_label, self.name.lower()] + model_state = state.models[app_label, self.name_lower] model_state.options = dict(model_state.options) model_state.options.update(self.options) for key in self.ALTER_OPTION_KEYS: if key not in self.options and key in model_state.options: del model_state.options[key] - state.reload_model(app_label, self.name) + state.reload_model(app_label, self.name_lower) def database_forwards(self, app_label, schema_editor, from_state, to_state): pass @@ -466,7 +507,7 @@ class AlterModelOptions(Operation): pass def references_model(self, name, app_label=None): - return name.lower() == self.name.lower() + return name.lower() == self.name_lower def describe(self): return "Change Meta options on %s" % (self.name, ) @@ -483,6 +524,10 @@ class AlterModelManagers(Operation): self.name = name self.managers = managers + @cached_property + def name_lower(self): + return self.name.lower() + def deconstruct(self): return ( self.__class__.__name__, @@ -491,7 +536,7 @@ class AlterModelManagers(Operation): ) def state_forwards(self, app_label, state): - model_state = state.models[app_label, self.name.lower()] + model_state = state.models[app_label, self.name_lower] model_state.managers = list(self.managers) def database_forwards(self, app_label, schema_editor, from_state, to_state): @@ -501,7 +546,7 @@ class AlterModelManagers(Operation): pass def references_model(self, name, app_label=None): - return name.lower() == self.name.lower() + return name.lower() == self.name_lower def describe(self): return "Change managers on %s" % (self.name, ) diff --git a/django/db/migrations/optimizer.py b/django/db/migrations/optimizer.py index d48ebcf90cd..be3983719ef 100644 --- a/django/db/migrations/optimizer.py +++ b/django/db/migrations/optimizer.py @@ -177,7 +177,7 @@ class MigrationOptimizer(object): """ Folds a CreateModel and a DeleteModel into nothing. """ - if (operation.name.lower() == other.name.lower() and + if (operation.name_lower == other.name_lower and not operation.options.get("proxy", False)): return [] @@ -185,14 +185,14 @@ class MigrationOptimizer(object): """ Folds an AlterModelSomething and a DeleteModel into just delete. """ - if operation.name.lower() == other.name.lower(): + if operation.name_lower == other.name_lower: return [other] def reduce_model_create_rename(self, operation, other, in_between): """ Folds a model rename into its create """ - if operation.name.lower() == other.old_name.lower(): + if operation.name_lower == other.old_name_lower: return [ migrations.CreateModel( other.new_name, @@ -206,7 +206,7 @@ class MigrationOptimizer(object): """ Folds a model rename into another one """ - if operation.new_name.lower() == other.old_name.lower(): + if operation.new_name_lower == other.old_name_lower: return [ migrations.RenameModel( operation.old_name, @@ -215,7 +215,7 @@ class MigrationOptimizer(object): ] def reduce_create_model_add_field(self, operation, other, in_between): - if operation.name.lower() == other.model_name.lower(): + if operation.name_lower == other.model_name_lower: # Don't allow optimisations of FKs through models they reference if hasattr(other.field, "rel") and other.field.rel: for between in in_between: @@ -239,7 +239,7 @@ class MigrationOptimizer(object): ] def reduce_create_model_alter_field(self, operation, other, in_between): - if operation.name.lower() == other.model_name.lower(): + if operation.name_lower == other.model_name_lower: return [ migrations.CreateModel( operation.name, @@ -253,7 +253,7 @@ class MigrationOptimizer(object): ] def reduce_create_model_rename_field(self, operation, other, in_between): - if operation.name.lower() == other.model_name.lower(): + if operation.name_lower == other.model_name_lower: return [ migrations.CreateModel( operation.name, @@ -267,14 +267,14 @@ class MigrationOptimizer(object): ] def reduce_create_model_remove_field(self, operation, other, in_between): - if operation.name.lower() == other.model_name.lower(): + if operation.name_lower == other.model_name_lower: return [ migrations.CreateModel( operation.name, fields=[ (n, v) for n, v in operation.fields - if n.lower() != other.name.lower() + if n.lower() != other.name_lower ], options=operation.options, bases=operation.bases, @@ -282,7 +282,8 @@ class MigrationOptimizer(object): ] def reduce_add_field_alter_field(self, operation, other, in_between): - if operation.model_name.lower() == other.model_name.lower() and operation.name.lower() == other.name.lower(): + if (operation.model_name_lower == other.model_name_lower and + operation.name_lower == other.name_lower): return [ migrations.AddField( model_name=operation.model_name, @@ -292,16 +293,18 @@ class MigrationOptimizer(object): ] def reduce_add_field_delete_field(self, operation, other, in_between): - if operation.model_name.lower() == other.model_name.lower() and operation.name.lower() == other.name.lower(): + if (operation.model_name_lower == other.model_name_lower and + operation.name_lower == other.name_lower): return [] def reduce_alter_field_delete_field(self, operation, other, in_between): - if operation.model_name.lower() == other.model_name.lower() and operation.name.lower() == other.name.lower(): + if (operation.model_name_lower == other.model_name_lower and + operation.name_lower == other.name_lower): return [other] def reduce_add_field_rename_field(self, operation, other, in_between): - if (operation.model_name.lower() == other.model_name.lower() and - operation.name.lower() == other.old_name.lower()): + if (operation.model_name_lower == other.model_name_lower and + operation.name_lower == other.old_name_lower): return [ migrations.AddField( model_name=operation.model_name, @@ -311,8 +314,8 @@ class MigrationOptimizer(object): ] def reduce_alter_field_rename_field(self, operation, other, in_between): - if (operation.model_name.lower() == other.model_name.lower() and - operation.name.lower() == other.old_name.lower()): + if (operation.model_name_lower == other.model_name_lower and + operation.name_lower == other.old_name_lower): return [ other, migrations.AlterField( @@ -323,8 +326,8 @@ class MigrationOptimizer(object): ] def reduce_rename_field_self(self, operation, other, in_between): - if (operation.model_name.lower() == other.model_name.lower() and - operation.new_name.lower() == other.old_name.lower()): + if (operation.model_name_lower == other.model_name_lower and + operation.new_name_lower == other.old_name_lower): return [ migrations.RenameField( operation.model_name, diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index 6626e31442c..84b8c0dbe93 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -33,13 +33,12 @@ class ProjectState(object): self.real_apps = real_apps or [] def add_model(self, model_state): - app_label, model_name = model_state.app_label, model_state.name.lower() + app_label, model_name = model_state.app_label, model_state.name_lower self.models[(app_label, model_name)] = model_state if 'apps' in self.__dict__: # hasattr would cache the property self.reload_model(app_label, model_name) def remove_model(self, app_label, model_name): - model_name = model_name.lower() del self.models[app_label, model_name] if 'apps' in self.__dict__: # hasattr would cache the property self.apps.unregister_model(app_label, model_name) @@ -47,7 +46,6 @@ class ProjectState(object): def reload_model(self, app_label, model_name): if 'apps' in self.__dict__: # hasattr would cache the property # Get relations before reloading the models, as _meta.apps may change - model_name = model_name.lower() try: related_old = { f.related_model for f in @@ -94,7 +92,7 @@ class ProjectState(object): app_models = {} for model in apps.get_models(include_swapped=True): model_state = ModelState.from_model(model) - app_models[(model_state.app_label, model_state.name.lower())] = model_state + app_models[(model_state.app_label, model_state.name_lower)] = model_state return cls(app_models) def __eq__(self, other): @@ -240,6 +238,10 @@ class ModelState(object): 'ModelState.fields cannot be bound to a model - "%s" is.' % name ) + @cached_property + def name_lower(self): + return self.name.lower() + @classmethod def from_model(cls, model, exclude_rels=False): """