mirror of
https://code.eliotberriot.com/funkwhale/funkwhale.git
synced 2025-10-03 23:29:15 +02:00
See #228: serializer logic
This commit is contained in:
parent
54008aa37c
commit
f1a1b93ee5
2 changed files with 163 additions and 0 deletions
74
api/funkwhale_api/common/serializers.py
Normal file
74
api/funkwhale_api/common/serializers.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
|
||||
class ActionSerializer(serializers.Serializer):
|
||||
"""
|
||||
A special serializer that can operate on a list of objects
|
||||
and apply actions on it.
|
||||
"""
|
||||
|
||||
action = serializers.CharField(required=True)
|
||||
objects = serializers.JSONField(required=True)
|
||||
filters = serializers.DictField(required=False)
|
||||
actions = None
|
||||
filterset_class = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.queryset = kwargs.pop('queryset')
|
||||
if self.actions is None:
|
||||
raise ValueError(
|
||||
'You must declare a list of actions on '
|
||||
'the serializer class')
|
||||
|
||||
for action in self.actions:
|
||||
handler_name = 'handle_{}'.format(action)
|
||||
assert hasattr(self, handler_name), (
|
||||
'{} miss a {} method'.format(
|
||||
self.__class__.__name__, handler_name)
|
||||
)
|
||||
super().__init__(self, *args, **kwargs)
|
||||
|
||||
def validate_action(self, value):
|
||||
if value not in self.actions:
|
||||
raise serializers.ValidationError(
|
||||
'{} is not a valid action. Pick one of {}.'.format(
|
||||
value, ', '.join(self.actions)
|
||||
)
|
||||
)
|
||||
return value
|
||||
|
||||
def validate_objects(self, value):
|
||||
qs = None
|
||||
if value == 'all':
|
||||
return self.queryset.all().order_by('id')
|
||||
if type(value) in [list, tuple]:
|
||||
return self.queryset.filter(pk__in=value).order_by('id')
|
||||
|
||||
raise serializers.ValidationError(
|
||||
'{} is not a valid value for objects. You must provide either a '
|
||||
'list of identifiers or the string "all".'.format(value))
|
||||
|
||||
def validate(self, data):
|
||||
if not self.filterset_class or 'filters' not in data:
|
||||
# no additional filters to apply, we just skip
|
||||
return data
|
||||
|
||||
qs_filterset = self.filterset_class(
|
||||
data['filters'], queryset=data['objects'])
|
||||
try:
|
||||
assert qs_filterset.form.is_valid()
|
||||
except (AssertionError, TypeError):
|
||||
raise serializers.ValidationError('Invalid filters')
|
||||
data['objects'] = qs_filterset.qs
|
||||
return data
|
||||
|
||||
def save(self):
|
||||
handler_name = 'handle_{}'.format(self.validated_data['action'])
|
||||
handler = getattr(self, handler_name)
|
||||
result = handler(self.validated_data['objects'])
|
||||
payload = {
|
||||
'updated': self.validated_data['objects'].count(),
|
||||
'action': self.validated_data['action'],
|
||||
'result': result,
|
||||
}
|
||||
return payload
|
Loading…
Add table
Add a link
Reference in a new issue