mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-05-11 16:53:10 +00:00
feat(api/2): Show all available fields by default
This commit is contained in:
parent
4fb09ad7ca
commit
30ec65fc13
5 changed files with 39 additions and 37 deletions
|
|
@ -81,7 +81,7 @@ class BaseAPIEndpoint(GenericViewSet):
|
|||
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
||||
return super(BaseAPIEndpoint, self).handle_exception(exc)
|
||||
|
||||
def get_api_fields(self, model):
|
||||
def get_available_fields(self, model):
|
||||
"""
|
||||
This returns a list of field names that are allowed to
|
||||
be used in the API (excluding the id field).
|
||||
|
|
@ -100,7 +100,7 @@ class BaseAPIEndpoint(GenericViewSet):
|
|||
query_parameters = set(self.request.GET.keys())
|
||||
|
||||
# All query paramters must be either a field or an operation
|
||||
allowed_query_parameters = set(self.get_api_fields(queryset.model)).union(self.known_query_parameters).union({'id'})
|
||||
allowed_query_parameters = set(self.get_available_fields(queryset.model)).union(self.known_query_parameters).union({'id'})
|
||||
unknown_parameters = query_parameters - allowed_query_parameters
|
||||
if unknown_parameters:
|
||||
raise BadRequestError("query parameter is not an operation or a recognised field: %s" % ', '.join(sorted(unknown_parameters)))
|
||||
|
|
@ -115,15 +115,17 @@ class BaseAPIEndpoint(GenericViewSet):
|
|||
model = type(self.get_object())
|
||||
|
||||
# Get all available fields
|
||||
all_fields = self.get_api_fields(model)
|
||||
all_fields = list(OrderedDict.fromkeys(all_fields)) # Removes any duplicates in case the developer put "title" in api_fields
|
||||
all_fields = self.get_available_fields(model)
|
||||
|
||||
# Remove any duplicates
|
||||
all_fields = list(OrderedDict.fromkeys(all_fields))
|
||||
|
||||
if self.action == 'listing_view':
|
||||
# Listing views just show the title field and any other allowed field the user specified
|
||||
if 'fields' in request.GET:
|
||||
fields = set(request.GET['fields'].split(','))
|
||||
else:
|
||||
fields = {'title'}
|
||||
fields = set(all_fields)
|
||||
|
||||
unknown_fields = fields - set(all_fields)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class FieldsFilter(BaseFilterBackend):
|
|||
This performs field level filtering on the result set
|
||||
Eg: ?title=James Joyce
|
||||
"""
|
||||
fields = set(view.get_api_fields(queryset.model)).union({'id'})
|
||||
fields = set(view.get_available_fields(queryset.model)).union({'id'})
|
||||
|
||||
for field_name, value in request.GET.items():
|
||||
if field_name in fields:
|
||||
|
|
@ -71,7 +71,7 @@ class OrderingFilter(BaseFilterBackend):
|
|||
reverse_order = False
|
||||
|
||||
# Add ordering
|
||||
if order_by == 'id' or order_by in view.get_api_fields(queryset.model):
|
||||
if order_by == 'id' or order_by in view.get_available_fields(queryset.model):
|
||||
queryset = queryset.order_by(order_by)
|
||||
else:
|
||||
# Unknown field
|
||||
|
|
|
|||
|
|
@ -56,37 +56,37 @@ class TestDocumentListing(TestCase):
|
|||
self.assertTrue(document['meta']['download_url'].startswith('http://localhost/documents/%d/' % document['id']))
|
||||
|
||||
|
||||
# EXTRA FIELDS
|
||||
# FIELDS
|
||||
|
||||
def test_extra_fields_default(self):
|
||||
def test_fields_default(self):
|
||||
response = self.get_response()
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
for document in content['results']:
|
||||
self.assertEqual(set(document.keys()), {'id', 'meta', 'title'})
|
||||
|
||||
def test_extra_fields(self):
|
||||
response = self.get_response(fields='title,tags')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
for document in content['results']:
|
||||
self.assertEqual(set(document.keys()), {'id', 'meta', 'title', 'tags'})
|
||||
|
||||
def test_extra_fields_tags(self):
|
||||
def test_fields(self):
|
||||
response = self.get_response(fields='title')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
for document in content['results']:
|
||||
self.assertEqual(set(document.keys()), {'id', 'meta', 'title'})
|
||||
|
||||
def test_fields_tags(self):
|
||||
response = self.get_response(fields='tags')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
for document in content['results']:
|
||||
self.assertIsInstance(document['tags'], list)
|
||||
|
||||
def test_extra_fields_which_are_not_in_api_fields_gives_error(self):
|
||||
def test_fields_which_are_not_in_api_fields_gives_error(self):
|
||||
response = self.get_response(fields='uploaded_by_user')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(content, {'message': "unknown fields: uploaded_by_user"})
|
||||
|
||||
def test_extra_fields_unknown_field_gives_error(self):
|
||||
def test_fields_unknown_field_gives_error(self):
|
||||
response = self.get_response(fields='123,title,abc')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
|
|
|
|||
|
|
@ -53,23 +53,23 @@ class TestImageListing(TestCase):
|
|||
self.assertEqual(image['meta']['detail_url'], 'http://localhost/api/v2beta/images/%d/' % image['id'])
|
||||
|
||||
|
||||
# EXTRA FIELDS
|
||||
# FIELDS
|
||||
|
||||
def test_extra_fields_default(self):
|
||||
def test_fields_default(self):
|
||||
response = self.get_response()
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
for image in content['results']:
|
||||
self.assertEqual(set(image.keys()), {'id', 'meta', 'title'})
|
||||
self.assertEqual(set(image.keys()), {'id', 'meta', 'title', 'width', 'height', 'tags'})
|
||||
|
||||
def test_extra_fields(self):
|
||||
def test_fields(self):
|
||||
response = self.get_response(fields='title,width,height')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
for image in content['results']:
|
||||
self.assertEqual(set(image.keys()), {'id', 'meta', 'title', 'width', 'height'})
|
||||
|
||||
def test_extra_fields_tags(self):
|
||||
def test_fields_tags(self):
|
||||
response = self.get_response(fields='tags')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
|
|
@ -77,14 +77,14 @@ class TestImageListing(TestCase):
|
|||
self.assertEqual(set(image.keys()), {'id', 'meta', 'tags'})
|
||||
self.assertIsInstance(image['tags'], list)
|
||||
|
||||
def test_extra_fields_which_are_not_in_api_fields_gives_error(self):
|
||||
def test_fields_which_are_not_in_api_fields_gives_error(self):
|
||||
response = self.get_response(fields='uploaded_by_user')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(content, {'message': "unknown fields: uploaded_by_user"})
|
||||
|
||||
def test_extra_fields_unknown_field_gives_error(self):
|
||||
def test_fields_unknown_field_gives_error(self):
|
||||
response = self.get_response(fields='123,title,abc')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
|
|
|
|||
|
|
@ -109,23 +109,23 @@ class TestPageListing(TestCase):
|
|||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(content, {'message': "type doesn't exist"})
|
||||
|
||||
# EXTRA FIELDS
|
||||
# FIELDS
|
||||
|
||||
def test_extra_fields_default(self):
|
||||
def test_fields_default(self):
|
||||
response = self.get_response(type='demosite.BlogEntryPage')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
for page in content['results']:
|
||||
self.assertEqual(set(page.keys()), {'id', 'meta', 'title'})
|
||||
self.assertEqual(set(page.keys()), {'id', 'meta', 'title', 'date', 'related_links', 'feed_image', 'body', 'carousel_items', 'tags'})
|
||||
|
||||
def test_extra_fields(self):
|
||||
def test_fields(self):
|
||||
response = self.get_response(type='demosite.BlogEntryPage', fields='title,date,feed_image')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
for page in content['results']:
|
||||
self.assertEqual(set(page.keys()), {'id', 'meta', 'title', 'date', 'feed_image'})
|
||||
|
||||
def test_extra_fields_child_relation(self):
|
||||
def test_fields_child_relation(self):
|
||||
response = self.get_response(type='demosite.BlogEntryPage', fields='title,related_links')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ class TestPageListing(TestCase):
|
|||
self.assertEqual(set(page.keys()), {'id', 'meta', 'title', 'related_links'})
|
||||
self.assertIsInstance(page['related_links'], list)
|
||||
|
||||
def test_extra_fields_foreign_key(self):
|
||||
def test_fields_foreign_key(self):
|
||||
response = self.get_response(type='demosite.BlogEntryPage', fields='title,date,feed_image')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ class TestPageListing(TestCase):
|
|||
self.assertEqual(feed_image['meta']['type'], 'wagtailimages.Image')
|
||||
self.assertEqual(feed_image['meta']['detail_url'], 'http://localhost/api/v2beta/images/%d/' % feed_image['id'])
|
||||
|
||||
def test_extra_fields_tags(self):
|
||||
def test_fields_tags(self):
|
||||
response = self.get_response(type='demosite.BlogEntryPage', fields='tags')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ class TestPageListing(TestCase):
|
|||
self.assertEqual(set(page.keys()), {'id', 'meta', 'tags'})
|
||||
self.assertIsInstance(page['tags'], list)
|
||||
|
||||
def test_extra_field_ordering(self):
|
||||
def test_fields_ordering(self):
|
||||
response = self.get_response(type='demosite.BlogEntryPage', fields='date,title,feed_image,related_links')
|
||||
|
||||
# Will crash if the JSON is invalid
|
||||
|
|
@ -175,21 +175,21 @@ class TestPageListing(TestCase):
|
|||
]
|
||||
self.assertEqual(list(content['results'][0].keys()), field_order)
|
||||
|
||||
def test_extra_fields_without_type_gives_error(self):
|
||||
def test_fields_without_type_gives_error(self):
|
||||
response = self.get_response(fields='title,related_links')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(content, {'message': "unknown fields: related_links"})
|
||||
|
||||
def test_extra_fields_which_are_not_in_api_fields_gives_error(self):
|
||||
def test_fields_which_are_not_in_api_fields_gives_error(self):
|
||||
response = self.get_response(fields='path')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(content, {'message': "unknown fields: path"})
|
||||
|
||||
def test_extra_fields_unknown_field_gives_error(self):
|
||||
def test_fields_unknown_field_gives_error(self):
|
||||
response = self.get_response(fields='123,title,abc')
|
||||
content = json.loads(response.content.decode('UTF-8'))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue