Created
August 10, 2021 12:21
-
-
Save jourdanrodrigues/6d8dcca9825163e3572b724a933bfe2d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Dict, Generator, List, Union | |
from rest_framework import serializers | |
from rest_framework.exceptions import ValidationError | |
from rest_framework.fields import empty | |
class EnhancedModelSerializer(serializers.ModelSerializer): | |
Meta: type | |
def __init__( | |
self, | |
instance=None, | |
data=empty, | |
exclude: List[str] = None, | |
skip_validation: bool = False, | |
**kwargs, | |
): | |
super().__init__(instance, data, **kwargs) | |
self.__skip_validation = skip_validation | |
self.__exclude_fields = exclude or [] | |
def to_internal_value(self, data): | |
if self.__skip_validation: | |
return data.copy() | |
return super().to_internal_value(data) | |
def get_excluded_fields(self) -> List[str]: | |
return self.__exclude_fields | |
@property | |
def _writable_fields(self) -> Generator[serializers.Field, None, None]: | |
for field in self.get_writable_fields().values(): | |
yield field | |
def get_writable_fields(self) -> Dict[str, serializers.Field]: | |
excluded = set(self.get_excluded_fields() + self._get_write_once_field_names()) | |
return { | |
name: field | |
for name, field in self.fields.items() | |
if not (field.read_only or name in excluded) | |
} | |
def _get_write_once_field_names(self) -> List[str]: | |
if self.instance is None: | |
return [] | |
return getattr(self.Meta, "write_once", []) | |
@property | |
def _readable_fields(self) -> Generator[serializers.Field, None, None]: | |
for field in self.get_readable_fields().values(): | |
yield field | |
def get_readable_fields(self) -> Dict[str, serializers.Field]: | |
excluded = set(self.get_excluded_fields()) | |
return { | |
name: field | |
for name, field in self.fields.items() | |
if not (field.write_only or name in excluded) | |
} | |
def bind_field( | |
self, | |
fields: dict, | |
field_name: str, | |
field: serializers.Field, | |
) -> None: | |
if self.partial: | |
field.required = False | |
field.bind(field_name, None) | |
fields[field_name] = field | |
def get_request(self) -> Request: | |
return self.context["request"] | |
def get_action(self) -> Union[str, None]: | |
return getattr(self.context["view"], "action", None) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment