diff options
| author | Matt Westcott <matt@west.co.tt> | 2015-02-14 01:22:38 +0000 |
|---|---|---|
| committer | Markus Holtermann <info@markusholtermann.eu> | 2015-05-26 17:10:02 +0200 |
| commit | ff8a02ae0b33ee52050e22909d432a3aa060d683 (patch) | |
| tree | bf40de3975777260ff4e55bd9e6459e369bd7c51 /django/db | |
| parent | 14f20c1fdc894dd348ec6a43eb4e0c5dd854d902 (diff) | |
Fixed #24340 -- Added nested deconstruction for list, tuple and dict values
Nested deconstruction should recursively deconstruct items within list,
tuple and dict values.
Diffstat (limited to 'django/db')
| -rw-r--r-- | django/db/migrations/autodetector.py | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index ad6aeda380..9a4ba42722 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -52,21 +52,35 @@ class MigrationAutodetector(object): Used for full comparison for rename/alter; sometimes a single-level deconstruction will not compare correctly. """ - if not hasattr(obj, 'deconstruct') or isinstance(obj, type): - return obj - deconstructed = obj.deconstruct() - if isinstance(obj, models.Field): - # we have a field which also returns a name - deconstructed = deconstructed[1:] - path, args, kwargs = deconstructed - return ( - path, - [self.deep_deconstruct(value) for value in args], - { + if isinstance(obj, list): + return [self.deep_deconstruct(value) for value in obj] + elif isinstance(obj, tuple): + return tuple(self.deep_deconstruct(value) for value in obj) + elif isinstance(obj, dict): + return { key: self.deep_deconstruct(value) - for key, value in kwargs.items() - }, - ) + for key, value in obj.items() + } + elif isinstance(obj, type): + # If this is a type that implements 'deconstruct' as an instance method, + # avoid treating this as being deconstructible itself - see #22951 + return obj + elif hasattr(obj, 'deconstruct'): + deconstructed = obj.deconstruct() + if isinstance(obj, models.Field): + # we have a field which also returns a name + deconstructed = deconstructed[1:] + path, args, kwargs = deconstructed + return ( + path, + [self.deep_deconstruct(value) for value in args], + { + key: self.deep_deconstruct(value) + for key, value in kwargs.items() + }, + ) + else: + return obj def only_relation_agnostic_fields(self, fields): """ |
