Last active
July 13, 2020 13:46
-
-
Save mjroson/9b0a4301dd5ba3f87c5f39463ff4ce26 to your computer and use it in GitHub Desktop.
This file contains 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 rest_framework.serializers import ModelSerializer | |
AVAILABLE_CONFIGS_FIELD = ('fields', 'read_only_fields', 'exclude', 'write_only_fields') | |
class BaseModelSerializer(ModelSerializer): | |
""" | |
Clase abstracta serializadora donde se pueden configurar campos para cada acciones genéricas de | |
las vistas ModelViewSet que provee DjangoRestFramework y acciones personalizadas | |
Serializer Ex: | |
class OrderSerializer(BaseModelSerializer): | |
class Meta: | |
model = Order | |
fields = "__all__" | |
fields_config = { | |
"create": { | |
"exclude": ("total",) | |
}, | |
"update": { | |
"fields": ("id", "total", "status", "delivery", "products"), | |
"read_only_fields": ("id", "total", "status") | |
}, | |
"change_status":{ # Custom action | |
"fields": ("status",) | |
} | |
} | |
View Ex: | |
class OrderModelViewSet(ModelViewSet): | |
serializer = OrderSerializer | |
queryset = Order.objects.all() | |
@detail_route(methods=['patch']) | |
def change_status(self, request, *args, **kwargs): | |
# Ejecutar logica de cambio de estado de una orden | |
# O simplemente dejar que django rest lo haga por defecto devolviendo el update | |
# El serializador se encarga de permitir modificar ciertos atributos de acuerdo a la firma del metodo | |
return super(OrderModelViewSet, self).update(request, *args, **kwargs) | |
""" | |
def __init__(self, *args, **kwargs): | |
if kwargs.get('context'): | |
action = kwargs['context']['view'].action | |
fields_config = getattr(self.Meta, 'fields_config') | |
if fields_config and fields_config.get(action): | |
custom_fields_by_action = fields_config.get(action) | |
if custom_fields_by_action.get('exclude') and getattr(self.Meta, 'fields', False): | |
delattr(self.Meta, 'fields') | |
elif custom_fields_by_action.get('fields') and getattr(self.Meta, 'exclude', False): | |
delattr(self.Meta, 'exclude') | |
for key, value in custom_fields_by_action.items(): | |
assert key in AVAILABLE_CONFIGS_FIELD, "The %s can't support" % key | |
setattr(self.Meta, key, value) | |
super(BaseModelSerializer, self).__init__(*args, **kwargs) | |
class Meta: | |
abstract = True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment