Cleanup how we handle inline serializers.

This commit is contained in:
Tom Hacohen 2020-04-15 15:23:07 +03:00
parent 5dfa2ac8cb
commit 963dc3c62d
2 changed files with 36 additions and 29 deletions

View File

@ -66,44 +66,40 @@ class CollectionItemChunkSerializer(serializers.ModelSerializer):
fields = ('uid', 'chunkFile')
class CollectionItemRevisionBaseSerializer(serializers.ModelSerializer):
class CollectionItemRevisionSerializer(serializers.ModelSerializer):
chunks = serializers.SlugRelatedField(
slug_field='uid',
queryset=models.CollectionItemChunk.objects.all(),
many=True
)
chunksUrls = serializers.SerializerMethodField('get_chunks_urls')
chunksData = serializers.SerializerMethodField('get_chunks_data')
meta = BinaryBase64Field()
class Meta:
model = models.CollectionItemRevision
fields = ('chunks', 'meta', 'uid', 'deleted')
class CollectionItemRevisionSerializer(CollectionItemRevisionBaseSerializer):
chunksUrls = serializers.SerializerMethodField('get_chunks_urls')
class Meta(CollectionItemRevisionBaseSerializer.Meta):
fields = CollectionItemRevisionBaseSerializer.Meta.fields + ('chunksUrls', )
fields = ('chunks', 'meta', 'uid', 'deleted', 'chunksUrls', 'chunksData')
# FIXME: currently the user is exposed in the url. We don't want that, and we can probably avoid that but still
# save it under the user.
# We would probably be better off just let the user calculate the urls from the uid and a base url for the snapshot.
# E.g. chunkBaseUrl: "/media/bla/bla/" or chunkBaseUrl: "https://media.etesync.com/bla/bla"
def get_chunks_urls(self, obj):
prefer_inline = self.context.get('prefer_inline', False)
if prefer_inline:
return None
ret = []
for chunk in obj.chunks.all():
ret.append(chunk.chunkFile.url)
return ret
class CollectionItemRevisionInlineSerializer(CollectionItemRevisionBaseSerializer):
chunksData = serializers.SerializerMethodField('get_chunks_data')
class Meta(CollectionItemRevisionBaseSerializer.Meta):
fields = CollectionItemRevisionBaseSerializer.Meta.fields + ('chunksData', )
def get_chunks_data(self, obj):
prefer_inline = self.context.get('prefer_inline', False)
if not prefer_inline:
return None
ret = []
for chunk in obj.chunks.all():
with open(chunk.chunkFile.path, 'rb') as f:
@ -111,6 +107,16 @@ class CollectionItemRevisionInlineSerializer(CollectionItemRevisionBaseSerialize
return ret
def to_representation(self, instance):
ret = super().to_representation(instance)
prefer_inline = self.context.get('prefer_inline', False)
if prefer_inline:
ret.pop('chunksUrls')
else:
ret.pop('chunksData')
return ret
class CollectionItemSerializer(serializers.ModelSerializer):
encryptionKey = BinaryBase64Field()
@ -154,10 +160,6 @@ class CollectionItemSerializer(serializers.ModelSerializer):
return instance
class CollectionItemInlineSerializer(CollectionItemSerializer):
content = CollectionItemRevisionInlineSerializer(read_only=True, many=False)
class CollectionSerializer(serializers.ModelSerializer):
encryptionKey = CollectionEncryptionKeyField()
accessLevel = serializers.SerializerMethodField('get_access_level_from_context')

View File

@ -29,7 +29,6 @@ from .models import Collection, CollectionItem
from .serializers import (
CollectionSerializer,
CollectionItemSerializer,
CollectionItemInlineSerializer,
CollectionItemRevisionSerializer,
CollectionItemChunkSerializer
)
@ -66,12 +65,18 @@ class CollectionViewSet(BaseViewSet):
queryset = type(self).queryset
return self.get_collection_queryset(queryset)
def get_serializer_context(self):
context = super().get_serializer_context()
prefer_inline = self.request.method == 'GET' and 'prefer_inline' in self.request.query_params
context.update({'request': self.request, 'prefer_inline': prefer_inline})
return context
def destroy(self, request, uid=None):
# FIXME: implement
return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
def create(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
serializer = self.serializer_class(data=request.data, context=self.get_serializer_context())
if serializer.is_valid():
try:
serializer.save(owner=self.request.user)
@ -86,7 +91,7 @@ class CollectionViewSet(BaseViewSet):
def list(self, request):
queryset = self.get_queryset()
serializer = self.serializer_class(queryset, context={'request': request}, many=True)
serializer = self.serializer_class(queryset, context=self.get_serializer_context(), many=True)
return Response(serializer.data)
@ -98,12 +103,6 @@ class CollectionItemViewSet(BaseViewSet):
pagination_class = paginators.LinkHeaderPagination
lookup_field = 'uid'
def get_serializer_class(self):
if self.request.method == 'GET' and self.request.query_params.get('prefer_inline'):
return CollectionItemInlineSerializer
return super().get_serializer_class()
def get_queryset(self):
collection_uid = self.kwargs['collection_uid']
try:
@ -117,6 +116,12 @@ class CollectionItemViewSet(BaseViewSet):
return queryset
def get_serializer_context(self):
context = super().get_serializer_context()
prefer_inline = self.request.method == 'GET' and 'prefer_inline' in self.request.query_params
context.update({'request': self.request, 'prefer_inline': prefer_inline})
return context
def create(self, request, collection_uid=None):
collection_object = get_object_or_404(self.get_collection_queryset(Collection.objects), uid=collection_uid)