Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

deconstruct.py 2.0KB

1 year ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. from importlib import import_module
  2. from django.utils.version import get_docs_version
  3. def deconstructible(*args, path=None):
  4. """
  5. Class decorator that allows the decorated class to be serialized
  6. by the migrations subsystem.
  7. The `path` kwarg specifies the import path.
  8. """
  9. def decorator(klass):
  10. def __new__(cls, *args, **kwargs):
  11. # We capture the arguments to make returning them trivial
  12. obj = super(klass, cls).__new__(cls)
  13. obj._constructor_args = (args, kwargs)
  14. return obj
  15. def deconstruct(obj):
  16. """
  17. Return a 3-tuple of class import path, positional arguments,
  18. and keyword arguments.
  19. """
  20. # Fallback version
  21. if path and type(obj) is klass:
  22. module_name, _, name = path.rpartition(".")
  23. else:
  24. module_name = obj.__module__
  25. name = obj.__class__.__name__
  26. # Make sure it's actually there and not an inner class
  27. module = import_module(module_name)
  28. if not hasattr(module, name):
  29. raise ValueError(
  30. "Could not find object %s in %s.\n"
  31. "Please note that you cannot serialize things like inner "
  32. "classes. Please move the object into the main module "
  33. "body to use migrations.\n"
  34. "For more information, see "
  35. "https://docs.djangoproject.com/en/%s/topics/migrations/"
  36. "#serializing-values" % (name, module_name, get_docs_version())
  37. )
  38. return (
  39. path
  40. if path and type(obj) is klass
  41. else f"{obj.__class__.__module__}.{name}",
  42. obj._constructor_args[0],
  43. obj._constructor_args[1],
  44. )
  45. klass.__new__ = staticmethod(__new__)
  46. klass.deconstruct = deconstruct
  47. return klass
  48. if not args:
  49. return decorator
  50. return decorator(*args)