36 lines
1.1 KiB
Python
36 lines
1.1 KiB
Python
|
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)
|