summaryrefslogtreecommitdiff
path: root/django/utils
diff options
context:
space:
mode:
Diffstat (limited to 'django/utils')
-rw-r--r--django/utils/deconstruct.py35
1 files changed, 35 insertions, 0 deletions
diff --git a/django/utils/deconstruct.py b/django/utils/deconstruct.py
new file mode 100644
index 0000000000..7774e69997
--- /dev/null
+++ b/django/utils/deconstruct.py
@@ -0,0 +1,35 @@
+def deconstructible(*args, **kwargs):
+ """
+ Class decorator that allow the decorated class to be serialized
+ by the migrations subsystem.
+
+ Accepts an optional kwarg `path` to specify the import path.
+ """
+ path = kwargs.pop('path', None)
+
+ def decorator(klass):
+ def __new__(cls, *args, **kwargs):
+ # We capture the arguments to make returning them trivial
+ obj = super(klass, cls).__new__(cls)
+ obj._constructor_args = (args, kwargs)
+ return obj
+
+ def deconstruct(obj):
+ """
+ Returns a 3-tuple of class import path, positional arguments,
+ and keyword arguments.
+ """
+ return (
+ path or '%s.%s' % (obj.__class__.__module__, obj.__class__.__name__),
+ obj._constructor_args[0],
+ obj._constructor_args[1],
+ )
+
+ klass.__new__ = staticmethod(__new__)
+ klass.deconstruct = deconstruct
+
+ return klass
+
+ if not args:
+ return decorator
+ return decorator(*args, **kwargs)