Added descendant_of support

This commit is contained in:
Michael Fillier 2015-07-10 10:59:40 -04:00 committed by Karl Hobley
parent 6bf7990e65
commit 577d3eeb92
2 changed files with 69 additions and 1 deletions

View file

@ -316,6 +316,7 @@ class PagesAPIEndpoint(BaseAPIEndpoint):
known_query_parameters = BaseAPIEndpoint.known_query_parameters.union([
'type',
'child_of',
'descendant_of',
])
def get_queryset(self, request, model=Page):
@ -386,12 +387,32 @@ class PagesAPIEndpoint(BaseAPIEndpoint):
try:
parent_page = self.get_queryset(request).get(id=parent_page_id)
return queryset.child_of(parent_page)
queryset = queryset.child_of(parent_page)
queryset._filtered_by_child_of = True
return queryset
except Page.DoesNotExist:
raise BadRequestError("parent page doesn't exist")
return queryset
def do_descendant_of_filter(self, request, queryset):
if 'descendant_of' in request.GET:
if getattr(queryset, '_filtered_by_child_of', False):
raise BadRequestError("filtering by descendant_of with child_of is not supported")
try:
ancestor_page_id = int(request.GET['descendant_of'])
assert ancestor_page_id >= 0
except (ValueError, AssertionError):
raise BadRequestError("descendant_of must be a positive integer")
try:
ancestor_page = self.get_queryset(request).get(id=ancestor_page_id)
return queryset.descendant_of(ancestor_page)
except Page.DoesNotExist:
raise BadRequestError("ancestor page doesn't exist")
return queryset
def listing_view(self, request):
# Get model and queryset
model = self.get_model(request)
@ -403,6 +424,7 @@ class PagesAPIEndpoint(BaseAPIEndpoint):
# Filtering
queryset = self.do_field_filtering(request, queryset)
queryset = self.do_child_of_filter(request, queryset)
queryset = self.do_descendant_of_filter(request, queryset)
# Ordering
queryset = self.do_ordering(request, queryset)

View file

@ -292,6 +292,52 @@ class TestPageListing(TestCase):
self.assertEqual(content, {'message': "parent page doesn't exist"})
# DESCENDANT OF FILTER
def test_descendant_of_filter(self):
response = self.get_response(descendant_of=6)
content = json.loads(response.content.decode('UTF-8'))
page_id_list = self.get_page_id_list(content)
self.assertEqual(page_id_list, [10, 15, 17, 21, 22, 23])
def test_descendant_of_with_type(self):
response = self.get_response(type='tests.EventPage', descendant_of=6)
content = json.loads(response.content.decode('UTF-8'))
page_id_list = self.get_page_id_list(content)
self.assertEqual(page_id_list, [])
def test_descendant_of_unknown_page_gives_error(self):
response = self.get_response(descendant_of=1000)
content = json.loads(response.content.decode('UTF-8'))
self.assertEqual(response.status_code, 400)
self.assertEqual(content, {'message': "ancestor page doesn't exist"})
def test_descendant_of_not_integer_gives_error(self):
response = self.get_response(descendant_of='abc')
content = json.loads(response.content.decode('UTF-8'))
self.assertEqual(response.status_code, 400)
self.assertEqual(content, {'message': "descendant_of must be a positive integer"})
def test_descendant_of_page_thats_not_in_same_site_gives_error(self):
# Root page is not in any site, so pretend it doesn't exist
response = self.get_response(descendant_of=1)
content = json.loads(response.content.decode('UTF-8'))
self.assertEqual(response.status_code, 400)
self.assertEqual(content, {'message': "ancestor page doesn't exist"})
def test_descendant_of_when_filtering_by_child_of_gives_error(self):
response = self.get_response(descendant_of=6, child_of=5)
content = json.loads(response.content.decode('UTF-8'))
self.assertEqual(response.status_code, 400)
self.assertEqual(content, {'message': "filtering by descendant_of with child_of is not supported"})
# ORDERING
def test_ordering_default(self):