Skip to content

Commit

Permalink
Return http 206 partial response when listing deleted objects and del…
Browse files Browse the repository at this point in the history
…etion limit is reached for the parent(s)
  • Loading branch information
vsemionov committed Aug 25, 2017
1 parent d004565 commit 77b7479
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 15 deletions.
15 changes: 1 addition & 14 deletions api/core/sync.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import datetime
from collections import OrderedDict

from django.conf import settings
from django.db import transaction
from django.utils import timezone, dateparse
from rest_framework import decorators, exceptions, status
from rest_framework import exceptions, status

from .mixin import ViewSetMixin

Expand Down Expand Up @@ -76,17 +74,6 @@ def list(self, request, *args, **kwargs):

return self.decorated_base_list(SyncedModelMixin, data, request, *args, **kwargs)

@decorators.list_route(suffix='Deleted List')
def deleted(self, request, *args, **kwargs):
self.deleted_object = True

response = self.list(request, *args, **kwargs)

if self.since is None or self.since < (timezone.now() - datetime.timedelta(settings.API_DELETED_EXPIRY_DAYS)):
response.status_code = status.HTTP_206_PARTIAL_CONTENT

return response


class ReadWriteSyncedModelMixin(SyncedModelMixin):

Expand Down
46 changes: 45 additions & 1 deletion api/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import datetime

from django.conf import settings
from django.utils import timezone
from django.contrib.auth.models import User
from rest_framework import viewsets, mixins, decorators
from django.db.models import Count, Min
from rest_framework import viewsets, mixins, decorators, status

from .models import Notebook, Note, Task
from .rest import serializers, links
Expand Down Expand Up @@ -42,6 +47,26 @@ class NestedViewSet(sort.SortedModelMixin,
filter_backends = (search.SearchFilter, sort.OrderingFilter)
ordering = sort.consistent_sort(sort.SortedModelMixin.DEFAULT_SORT)

def _is_deleted_expired_possible(self):
if self.since is None:
return True
return self.since < (timezone.now() - datetime.timedelta(settings.API_DELETED_EXPIRY_DAYS))

def _is_deleted_exceeded_possible(self):
del_limit = self._get_limit(True)
if not del_limit:
return False

filter_kwargs = {expr: self.kwargs[kwarg] for expr, kwarg in self.object_filters.items()}
filter_kwargs['deleted'] = True

results = self.queryset.filter(**filter_kwargs)
results = results.values(self.parent_key_filter[0])
results = results.annotate(ndel=Count('*'), oldest=Min('updated'))
results = results.filter(ndel__gte=del_limit, oldest__gte=self.since)

return len(results) > 0

def get_hyperlinked_serializer_class(self, username):
raise NotImplementedError()

Expand All @@ -51,6 +76,17 @@ def get_serializer_class(self):
else:
return self.get_hyperlinked_serializer_class(self.kwargs['user_username'])

@decorators.list_route(suffix='Deleted List')
def deleted(self, request, *args, **kwargs):
self.deleted_object = True

response = self.list(request, *args, **kwargs)

if self._is_deleted_expired_possible() or self._is_deleted_exceeded_possible():
response.status_code = status.HTTP_206_PARTIAL_CONTENT

return response

@decorators.list_route(suffix='Search')
def search(self, request, *args, **kwargs):
self.explicit_search = True
Expand Down Expand Up @@ -132,10 +168,18 @@ class UserNoteViewSet(sort.SortedModelMixin,
safe_parent = True
object_filters = {'notebook__user_id': 'user_username'}
# parent_filters = {'user_id': 'user_username'}
parent_key_filter = ('notebook_id', None)

_get_limit = NestedViewSet._get_limit

_is_deleted_expired_possible = NestedViewSet._is_deleted_expired_possible
_is_deleted_exceeded_possible = NestedViewSet._is_deleted_exceeded_possible

get_serializer_class = NestedViewSet.get_serializer_class
get_hyperlinked_serializer_class = staticmethod(links.create_hyperlinked_note_serializer_class)

deleted = NestedViewSet.deleted

def get_view_name(self):
name = self.view_name
if self.suffix:
Expand Down

0 comments on commit 77b7479

Please sign in to comment.