fields.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. from collections import OrderedDict
  2. from typing import List
  3. from rest_framework import serializers
  4. from rest_framework.exceptions import ValidationError, ErrorDetail
  5. class ErrorValueDetail(ErrorDetail):
  6. """Extended ErrorDetail with validation value"""
  7. value = None
  8. def __new__(cls, string, code=None, value=None):
  9. self = super().__new__(cls, string, code)
  10. self.value = value
  11. return self
  12. def __repr__(self):
  13. return "ErrorDetail(string=%r, code=%r, value=%r)" % (
  14. str(self),
  15. self.code,
  16. self.value,
  17. )
  18. class GenericField(serializers.Field):
  19. def to_internal_value(self, data):
  20. return data
  21. class ForgivingHStoreField(serializers.HStoreField):
  22. def run_child_validation(self, data):
  23. result = {}
  24. errors = OrderedDict()
  25. for key, value in data.items():
  26. if value is None:
  27. continue
  28. key = str(key)
  29. try:
  30. result[key] = self.child.run_validation(value)
  31. except ValidationError as e:
  32. details: List[ErrorValueDetail] = []
  33. for detail in e.detail:
  34. details.append(ErrorValueDetail(str(detail), detail.code, value))
  35. errors[key] = details
  36. if errors:
  37. handled_errors = self.context.get("handled_errors", {})
  38. self.context["handled_errors"] = handled_errors | {self.field_name: errors}
  39. return result