Files
outbo-2-stgclone/evg-outbo-api/patches.py
T
2024-11-27 13:18:16 +01:00

92 lines
2.9 KiB
Python
Executable File

from deepmerge import Merger, STRATEGY_END
from django.db.models.signals import class_prepared
from django.utils.functional import curry
from django_fsm import (
FSMFieldMixin,
get_all_FIELD_transitions,
get_available_FIELD_transitions,
get_available_user_FIELD_transitions,
)
from rest_framework.request import _hasattr, is_form_media_type, Request
__all__ = ["patches"]
def merge_dicts(config, path, base, nxt):
if isinstance(base, list) and isinstance(nxt, list) and len(base) == len(nxt):
data = [{**a, **b} for a, b in zip(base, nxt)]
return data
return STRATEGY_END
merger = Merger(
[(list, merge_dicts), (list, "append"), (dict, "merge")], ["override"], ["override"]
)
def _patched_load_data_and_files(self):
"""
Parses the request content into `self.data`.
"""
if not _hasattr(self, "_data"):
self._data, self._files = self._parse()
if self._files:
self._full_data = merger.merge(self._data, self._files)
else:
self._full_data = self._data
# if a form media type, copy data & files refs to the underlying
# http request so that closable objects are handled appropriately.
if is_form_media_type(self.content_type):
self._request._post = self.POST
self._request._files = self.FILES
def _modified_contribute_to_class(self, cls, name, **kwargs):
self.base_cls = cls
super(FSMFieldMixin, self).contribute_to_class(cls, name, **kwargs)
setattr(cls, f"{self.name}_description", self.descriptor_class(self))
setattr(
cls,
"get_all_{0}_transitions".format(self.name),
curry(get_all_FIELD_transitions, field=self),
)
setattr(
cls,
"get_available_{0}_transitions".format(self.name),
curry(get_available_FIELD_transitions, field=self),
)
setattr(
cls,
"get_available_user_{0}_transitions".format(self.name),
curry(get_available_user_FIELD_transitions, field=self),
)
class_prepared.connect(self._collect_transitions)
# Do not obscure related model in FSMKeyField
# Pull request https://github.com/viewflow/django-fsm/pull/200/files#diff-7b4b9604f1842ff54833d14e644e9710
class Patches:
def __init__(self):
self._load_data_and_files = None
self._contribute_to_class = None
def on(self):
self._load_data_and_files = Request._load_data_and_files
self._contribute_to_class = FSMFieldMixin.contribute_to_class
Request._load_data_and_files = _patched_load_data_and_files
FSMFieldMixin.contribute_to_class = _modified_contribute_to_class
def off(self):
if self._load_data_and_files:
Request._load_data_and_files = self._load_data_and_files
if self._contribute_to_class:
FSMFieldMixin.contribute_to_class = self._contribute_to_class
patches = Patches()