Last active
August 27, 2020 05:53
-
-
Save mentix02/c8e09b100839ba714a101aa9c3bfe213 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UpdatePostAPIView(APIView): | |
permission_classes = (IsAuthenticated,) | |
parser_classes = (MultiPartParser, FormParser) | |
@staticmethod | |
def get(request: WSGIRequest, pk: int) -> Response: | |
try: | |
# Solves the problem of checking whether user owns post referenced. | |
post = Post.objects.filter(user=request.user).get(pk=pk) | |
except Post.DoesNotExist: | |
return Response({'detail': 'Not found.'}, status=status.HTTP_404_NOT_FOUND) | |
else: | |
return Response(PostSerializer(post).data) | |
@staticmethod | |
def put(request: WSGIRequest, pk: int) -> Response: | |
try: | |
# Solves the problem of checking whether user owns post referenced. | |
post = Post.objects.filter(user=request.user).get(pk=pk) | |
except Post.DoesNotExist: | |
return Response({'detail': 'Not found.'}, status=status.HTTP_404_NOT_FOUND) | |
# Provides a list of ids for images to be deleted. | |
to_delete = set(map(int, request.POST.getlist('to_delete'))) | |
# Provides a list of additional (or replacement) images to be uploaded. | |
additional_images = request.FILES.getlist('images') | |
post_images = post.images.all() | |
post_images_count = post_images.count() | |
final_images_count = post_images_count - len(to_delete) + len(additional_images) | |
if final_images_count > 5 or final_images_count <= 0: | |
# Check if the difference between the number of images requested to be deleted | |
# and the total number of images currently in post added with the total number | |
# new images to be uploaded lies between 0 and 5. | |
return Response( | |
{'detail': 'Cannot have post with 0 images.'}, | |
status=status.HTTP_400_BAD_REQUEST, | |
) | |
elif to_delete.issubset(set(post_images.values_list('pk', flat=True))): | |
# Default case if everything goes right since only two situations can evaluate | |
# the above clause to be true - | |
# 1. Either no new images were provided and thus an empty set will always be | |
# a subset to all the images already existing in the post OR | |
# 2. The ids that were provided in to_delete were valid ids that belong to the | |
# id list of the images reversely to the post. | |
# Bulk delete images if any. | |
post_images.filter(id__in=to_delete).delete() | |
# Upload images if any. | |
for image in additional_images: | |
image_serializer = ImageSerializer( | |
data={'file': image, 'post': post.id} | |
) | |
if image_serializer.is_valid(): | |
image_serializer.save() | |
else: | |
return Response( | |
{'error': 'Invalid image data.'}, | |
status=status.HTTP_409_CONFLICT, | |
) | |
else: | |
# Everything has gone right so far and a sanitary update of caption is left. | |
if request.POST.get('caption', False): | |
post.caption = request.POST['caption'] | |
post.save() | |
return Response({'success': 'Updated.'}, status=status.HTTP_200_OK) | |
else: | |
return Response({'error': 'Not found.'}, status=status.HTTP_404_NOT_FOUND) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment