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