Refs #22608 -- Optimized migration optimizer and migrate by caching calls to str.lower()

This commit is contained in:
Ulrich Petri 2015-01-02 16:37:21 +01:00 committed by Tim Graham
parent ee86e59051
commit 391bb09bb0
5 changed files with 180 additions and 91 deletions

View File

@ -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

View File

@ -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
)

View File

@ -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, )

View File

@ -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,

View File

@ -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):
"""