summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/migrations/operations/models.py90
1 files changed, 30 insertions, 60 deletions
diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py
index 8ae877b5fe..f286bf4ea4 100644
--- a/django/db/migrations/operations/models.py
+++ b/django/db/migrations/operations/models.py
@@ -491,22 +491,23 @@ class FieldRelatedOptionOperation(ModelOptionOperation):
return super().reduce(operation, app_label=app_label)
-class AlterUniqueTogether(FieldRelatedOptionOperation):
- """
- Change the value of unique_together to the target one.
- Input value of unique_together must be a set of tuples.
- """
- option_name = "unique_together"
+class AlterTogetherOptionOperation(FieldRelatedOptionOperation):
+ option_name = None
- def __init__(self, name, unique_together):
- unique_together = normalize_together(unique_together)
- self.unique_together = {tuple(cons) for cons in unique_together}
+ def __init__(self, name, option_value):
+ if option_value:
+ option_value = set(normalize_together(option_value))
+ setattr(self, self.option_name, option_value)
super().__init__(name)
+ @cached_property
+ def option_value(self):
+ return getattr(self, self.option_name)
+
def deconstruct(self):
kwargs = {
'name': self.name,
- 'unique_together': self.unique_together,
+ self.option_name: self.option_value,
}
return (
self.__class__.__qualname__,
@@ -516,14 +517,15 @@ class AlterUniqueTogether(FieldRelatedOptionOperation):
def state_forwards(self, app_label, state):
model_state = state.models[app_label, self.name_lower]
- model_state.options[self.option_name] = self.unique_together
+ model_state.options[self.option_name] = self.option_value
state.reload_model(app_label, self.name_lower, delay=True)
def database_forwards(self, app_label, schema_editor, from_state, to_state):
new_model = to_state.apps.get_model(app_label, self.name)
if self.allow_migrate_model(schema_editor.connection.alias, new_model):
old_model = from_state.apps.get_model(app_label, self.name)
- schema_editor.alter_unique_together(
+ alter_together = getattr(schema_editor, 'alter_%s' % self.option_name)
+ alter_together(
new_model,
getattr(old_model._meta, self.option_name, set()),
getattr(new_model._meta, self.option_name, set()),
@@ -536,16 +538,27 @@ class AlterUniqueTogether(FieldRelatedOptionOperation):
return (
self.references_model(model_name, app_label) and
(
- not self.unique_together or
- any((name in together) for together in self.unique_together)
+ not self.option_value or
+ any((name in fields) for fields in self.option_value)
)
)
def describe(self):
- return "Alter %s for %s (%s constraint(s))" % (self.option_name, self.name, len(self.unique_together or ''))
+ return "Alter %s for %s (%s constraint(s))" % (self.option_name, self.name, len(self.option_value or ''))
+
+
+class AlterUniqueTogether(AlterTogetherOptionOperation):
+ """
+ Change the value of unique_together to the target one.
+ Input value of unique_together must be a set of tuples.
+ """
+ option_name = 'unique_together'
+
+ def __init__(self, name, unique_together):
+ super().__init__(name, unique_together)
-class AlterIndexTogether(FieldRelatedOptionOperation):
+class AlterIndexTogether(AlterTogetherOptionOperation):
"""
Change the value of index_together to the target one.
Input value of index_together must be a set of tuples.
@@ -553,50 +566,7 @@ class AlterIndexTogether(FieldRelatedOptionOperation):
option_name = "index_together"
def __init__(self, name, index_together):
- index_together = normalize_together(index_together)
- self.index_together = {tuple(cons) for cons in index_together}
- super().__init__(name)
-
- def deconstruct(self):
- kwargs = {
- 'name': self.name,
- 'index_together': self.index_together,
- }
- return (
- self.__class__.__qualname__,
- [],
- kwargs
- )
-
- def state_forwards(self, app_label, state):
- 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_lower, delay=True)
-
- def database_forwards(self, app_label, schema_editor, from_state, to_state):
- new_model = to_state.apps.get_model(app_label, self.name)
- if self.allow_migrate_model(schema_editor.connection.alias, new_model):
- old_model = from_state.apps.get_model(app_label, self.name)
- schema_editor.alter_index_together(
- new_model,
- getattr(old_model._meta, self.option_name, set()),
- getattr(new_model._meta, self.option_name, set()),
- )
-
- def database_backwards(self, app_label, schema_editor, from_state, to_state):
- return self.database_forwards(app_label, schema_editor, from_state, to_state)
-
- def references_field(self, model_name, name, app_label=None):
- return (
- self.references_model(model_name, app_label) and
- (
- not self.index_together or
- any((name in together) for together in self.index_together)
- )
- )
-
- def describe(self):
- return "Alter %s for %s (%s constraint(s))" % (self.option_name, self.name, len(self.index_together or ''))
+ super().__init__(name, index_together)
class AlterOrderWithRespectTo(FieldRelatedOptionOperation):