Skip to content

Instantly share code, notes, and snippets.

@mjroson
Last active July 13, 2020 13:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjroson/9b0a4301dd5ba3f87c5f39463ff4ce26 to your computer and use it in GitHub Desktop.
Save mjroson/9b0a4301dd5ba3f87c5f39463ff4ce26 to your computer and use it in GitHub Desktop.
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