Batch: refactor code and allow passing deps to check against.
This commit is contained in:
parent
653341115f
commit
23b2bb3c0a
@ -316,73 +316,48 @@ class CollectionItemViewSet(BaseViewSet):
|
|||||||
|
|
||||||
@action_decorator(detail=False, methods=['POST'])
|
@action_decorator(detail=False, methods=['POST'])
|
||||||
def batch(self, request, collection_uid=None):
|
def batch(self, request, collection_uid=None):
|
||||||
stoken = request.GET.get('stoken', None)
|
return self.transaction(request, collection_uid, validate_etag=False)
|
||||||
collection_object = get_object_or_404(self.get_collection_queryset(Collection.objects), uid=collection_uid)
|
|
||||||
|
|
||||||
if stoken is not None and stoken != collection_object.stoken:
|
|
||||||
content = {'code': 'stale_stoken', 'detail': 'Stoken is too old'}
|
|
||||||
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
items = request.data.get('items')
|
|
||||||
serializer = self.get_serializer(data=items, many=True)
|
|
||||||
|
|
||||||
if serializer.is_valid():
|
|
||||||
try:
|
|
||||||
with transaction.atomic():
|
|
||||||
items = serializer.save(collection=collection_object)
|
|
||||||
except IntegrityError:
|
|
||||||
# FIXME: should return the items with a bad token (including deps) so we don't have to fetch them after
|
|
||||||
content = {'code': 'integrity_error'}
|
|
||||||
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
ret = {
|
|
||||||
}
|
|
||||||
return Response(ret, status=status.HTTP_200_OK)
|
|
||||||
|
|
||||||
return Response(
|
|
||||||
{
|
|
||||||
"items": serializer.errors,
|
|
||||||
},
|
|
||||||
status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
@action_decorator(detail=False, methods=['POST'])
|
@action_decorator(detail=False, methods=['POST'])
|
||||||
def transaction(self, request, collection_uid=None):
|
def transaction(self, request, collection_uid=None, validate_etag=True):
|
||||||
stoken = request.GET.get('stoken', None)
|
stoken = request.GET.get('stoken', None)
|
||||||
collection_object = get_object_or_404(self.get_collection_queryset(Collection.objects), uid=collection_uid)
|
with transaction.atomic(): # We need this for locking on the collection object
|
||||||
|
collection_object = get_object_or_404(
|
||||||
|
self.get_collection_queryset(Collection.objects).select_for_update(), # Lock writes on the collection
|
||||||
|
uid=collection_uid)
|
||||||
|
|
||||||
if stoken is not None and stoken != collection_object.stoken:
|
if stoken is not None and stoken != collection_object.stoken:
|
||||||
content = {'code': 'stale_stoken', 'detail': 'Stoken is too old'}
|
content = {'code': 'stale_stoken', 'detail': 'Stoken is too old'}
|
||||||
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
items = request.data.get('items')
|
|
||||||
deps = request.data.get('deps', None)
|
|
||||||
# FIXME: It should just be one serializer
|
|
||||||
context = self.get_serializer_context()
|
|
||||||
context.update({'validate_etag': True})
|
|
||||||
serializer = self.get_serializer_class()(data=items, context=context, many=True)
|
|
||||||
deps_serializer = CollectionItemDepSerializer(data=deps, context=context, many=True)
|
|
||||||
|
|
||||||
ser_valid = serializer.is_valid()
|
|
||||||
deps_ser_valid = (deps is None or deps_serializer.is_valid())
|
|
||||||
if ser_valid and deps_ser_valid:
|
|
||||||
try:
|
|
||||||
with transaction.atomic():
|
|
||||||
items = serializer.save(collection=collection_object)
|
|
||||||
except IntegrityError:
|
|
||||||
# FIXME: should return the items with a bad token (including deps) so we don't have to fetch them after
|
|
||||||
content = {'code': 'integrity_error'}
|
|
||||||
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
ret = {
|
items = request.data.get('items')
|
||||||
}
|
deps = request.data.get('deps', None)
|
||||||
return Response(ret, status=status.HTTP_200_OK)
|
# FIXME: It should just be one serializer
|
||||||
|
context = self.get_serializer_context()
|
||||||
|
context.update({'validate_etag': validate_etag})
|
||||||
|
serializer = self.get_serializer_class()(data=items, context=context, many=True)
|
||||||
|
deps_serializer = CollectionItemDepSerializer(data=deps, context=context, many=True)
|
||||||
|
|
||||||
return Response(
|
ser_valid = serializer.is_valid()
|
||||||
{
|
deps_ser_valid = (deps is None or deps_serializer.is_valid())
|
||||||
"items": serializer.errors,
|
if ser_valid and deps_ser_valid:
|
||||||
"deps": deps_serializer.errors if deps is not None else [],
|
try:
|
||||||
},
|
items = serializer.save(collection=collection_object)
|
||||||
status=status.HTTP_400_BAD_REQUEST)
|
except IntegrityError:
|
||||||
|
# FIXME: return the items with a bad token (including deps) so we don't have to fetch them after
|
||||||
|
content = {'code': 'integrity_error'}
|
||||||
|
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
ret = {
|
||||||
|
}
|
||||||
|
return Response(ret, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"items": serializer.errors,
|
||||||
|
"deps": deps_serializer.errors if deps is not None else [],
|
||||||
|
},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
class CollectionItemChunkViewSet(viewsets.ViewSet):
|
class CollectionItemChunkViewSet(viewsets.ViewSet):
|
||||||
|
Loading…
Reference in New Issue
Block a user