summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormanav014 <dpsman13016@gmail.com>2021-06-22 09:14:27 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-06-22 09:26:18 +0200
commitd718d99017b83987fe994fab968d6c3039f352b2 (patch)
tree528d20f9c1723e90c18e26a0ed96c4c7ca2c354e
parente85d9c02ad1ef8988c149bad905fbc5b98a38594 (diff)
Refs #29898 -- Moved django.db.migrations.operations.utils to django.db.migrations.utils.
-rw-r--r--django/db/migrations/operations/fields.py4
-rw-r--r--django/db/migrations/operations/models.py5
-rw-r--r--django/db/migrations/operations/utils.py74
-rw-r--r--django/db/migrations/utils.py72
4 files changed, 78 insertions, 77 deletions
diff --git a/django/db/migrations/operations/fields.py b/django/db/migrations/operations/fields.py
index 728105ea05..b303f70465 100644
--- a/django/db/migrations/operations/fields.py
+++ b/django/db/migrations/operations/fields.py
@@ -1,9 +1,11 @@
from django.core.exceptions import FieldDoesNotExist
+from django.db.migrations.utils import (
+ field_is_referenced, field_references, get_references,
+)
from django.db.models import NOT_PROVIDED
from django.utils.functional import cached_property
from .base import Operation
-from .utils import field_is_referenced, field_references, get_references
class FieldOperation(Operation):
diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py
index a39731e412..10f2686dc6 100644
--- a/django/db/migrations/operations/models.py
+++ b/django/db/migrations/operations/models.py
@@ -1,14 +1,15 @@
from django.db import models
from django.db.migrations.operations.base import Operation
from django.db.migrations.state import ModelState
-from django.db.migrations.utils import resolve_relation
+from django.db.migrations.utils import (
+ field_references, get_references, resolve_relation,
+)
from django.db.models.options import normalize_together
from django.utils.functional import cached_property
from .fields import (
AddField, AlterField, FieldOperation, RemoveField, RenameField,
)
-from .utils import field_references, get_references
def _check_for_duplicates(arg_name, objs):
diff --git a/django/db/migrations/operations/utils.py b/django/db/migrations/operations/utils.py
deleted file mode 100644
index 0ea55bd3f7..0000000000
--- a/django/db/migrations/operations/utils.py
+++ /dev/null
@@ -1,74 +0,0 @@
-from collections import namedtuple
-
-from django.db.migrations.utils import resolve_relation
-
-FieldReference = namedtuple('FieldReference', 'to through')
-
-
-def field_references(
- model_tuple,
- field,
- reference_model_tuple,
- reference_field_name=None,
- reference_field=None,
-):
- """
- Return either False or a FieldReference if `field` references provided
- context.
-
- False positives can be returned if `reference_field_name` is provided
- without `reference_field` because of the introspection limitation it
- incurs. This should not be an issue when this function is used to determine
- whether or not an optimization can take place.
- """
- remote_field = field.remote_field
- if not remote_field:
- return False
- references_to = None
- references_through = None
- if resolve_relation(remote_field.model, *model_tuple) == reference_model_tuple:
- to_fields = getattr(field, 'to_fields', None)
- if (
- reference_field_name is None or
- # Unspecified to_field(s).
- to_fields is None or
- # Reference to primary key.
- (None in to_fields and (reference_field is None or reference_field.primary_key)) or
- # Reference to field.
- reference_field_name in to_fields
- ):
- references_to = (remote_field, to_fields)
- through = getattr(remote_field, 'through', None)
- if through and resolve_relation(through, *model_tuple) == reference_model_tuple:
- through_fields = remote_field.through_fields
- if (
- reference_field_name is None or
- # Unspecified through_fields.
- through_fields is None or
- # Reference to field.
- reference_field_name in through_fields
- ):
- references_through = (remote_field, through_fields)
- if not (references_to or references_through):
- return False
- return FieldReference(references_to, references_through)
-
-
-def get_references(state, model_tuple, field_tuple=()):
- """
- Generator of (model_state, name, field, reference) referencing
- provided context.
-
- If field_tuple is provided only references to this particular field of
- model_tuple will be generated.
- """
- for state_model_tuple, model_state in state.models.items():
- for name, field in model_state.fields.items():
- reference = field_references(state_model_tuple, field, model_tuple, *field_tuple)
- if reference:
- yield model_state, name, field, reference
-
-
-def field_is_referenced(state, model_tuple, field_tuple):
- """Return whether `field_tuple` is referenced by any state models."""
- return next(get_references(state, model_tuple, field_tuple), None) is not None
diff --git a/django/db/migrations/utils.py b/django/db/migrations/utils.py
index 7ce2c5bc82..97bd96a90a 100644
--- a/django/db/migrations/utils.py
+++ b/django/db/migrations/utils.py
@@ -1,8 +1,11 @@
import datetime
import re
+from collections import namedtuple
from django.db.models.fields.related import RECURSIVE_RELATIONSHIP_CONSTANT
+FieldReference = namedtuple('FieldReference', 'to through')
+
COMPILED_REGEX_TYPE = type(re.compile(''))
@@ -44,3 +47,72 @@ def resolve_relation(model, app_label=None, model_name=None):
)
return app_label, model.lower()
return model._meta.app_label, model._meta.model_name
+
+
+def field_references(
+ model_tuple,
+ field,
+ reference_model_tuple,
+ reference_field_name=None,
+ reference_field=None,
+):
+ """
+ Return either False or a FieldReference if `field` references provided
+ context.
+
+ False positives can be returned if `reference_field_name` is provided
+ without `reference_field` because of the introspection limitation it
+ incurs. This should not be an issue when this function is used to determine
+ whether or not an optimization can take place.
+ """
+ remote_field = field.remote_field
+ if not remote_field:
+ return False
+ references_to = None
+ references_through = None
+ if resolve_relation(remote_field.model, *model_tuple) == reference_model_tuple:
+ to_fields = getattr(field, 'to_fields', None)
+ if (
+ reference_field_name is None or
+ # Unspecified to_field(s).
+ to_fields is None or
+ # Reference to primary key.
+ (None in to_fields and (reference_field is None or reference_field.primary_key)) or
+ # Reference to field.
+ reference_field_name in to_fields
+ ):
+ references_to = (remote_field, to_fields)
+ through = getattr(remote_field, 'through', None)
+ if through and resolve_relation(through, *model_tuple) == reference_model_tuple:
+ through_fields = remote_field.through_fields
+ if (
+ reference_field_name is None or
+ # Unspecified through_fields.
+ through_fields is None or
+ # Reference to field.
+ reference_field_name in through_fields
+ ):
+ references_through = (remote_field, through_fields)
+ if not (references_to or references_through):
+ return False
+ return FieldReference(references_to, references_through)
+
+
+def get_references(state, model_tuple, field_tuple=()):
+ """
+ Generator of (model_state, name, field, reference) referencing
+ provided context.
+
+ If field_tuple is provided only references to this particular field of
+ model_tuple will be generated.
+ """
+ for state_model_tuple, model_state in state.models.items():
+ for name, field in model_state.fields.items():
+ reference = field_references(state_model_tuple, field, model_tuple, *field_tuple)
+ if reference:
+ yield model_state, name, field, reference
+
+
+def field_is_referenced(state, model_tuple, field_tuple):
+ """Return whether `field_tuple` is referenced by any state models."""
+ return next(get_references(state, model_tuple, field_tuple), None) is not None