118_API_update #119

Merged
mpeltriaux merged 2 commits from 118_API_update into master 2022-02-16 11:39:17 +01:00
4 changed files with 71 additions and 15 deletions
Showing only changes of commit c7382f1e54 - Show all commits

View File

@ -36,7 +36,12 @@ class APIV1GetTestCase(BaseAPIV1TestCase):
""" """
response = self._run_get_request(url) response = self._run_get_request(url)
content = json.loads(response.content) content = json.loads(response.content)
geojson = content[str(obj.id)] self.assertIn("rpp", content)
self.assertIn("p", content)
self.assertIn("next", content)
self.assertIn("results", content)
paginated_content = content["results"]
geojson = paginated_content[str(obj.id)]
self.assertEqual(response.status_code, 200, msg=response.content) self.assertEqual(response.status_code, 200, msg=response.content)
return geojson return geojson

View File

@ -10,6 +10,7 @@ from abc import abstractmethod
from django.contrib.gis import geos from django.contrib.gis import geos
from django.contrib.gis.geos import GEOSGeometry from django.contrib.gis.geos import GEOSGeometry
from django.core.paginator import Paginator
from konova.utils.message_templates import DATA_UNSHARED from konova.utils.message_templates import DATA_UNSHARED
@ -19,6 +20,10 @@ class AbstractModelAPISerializer:
lookup = None lookup = None
properties_data = None properties_data = None
rpp = None
page_number = None
paginator = None
class Meta: class Meta:
abstract = True abstract = True
@ -80,9 +85,12 @@ class AbstractModelAPISerializer:
Returns: Returns:
serialized_data (dict) serialized_data (dict)
""" """
entries = self.model.objects.filter(**self.lookup) entries = self.model.objects.filter(**self.lookup).order_by("id")
self.paginator = Paginator(entries, self.rpp)
requested_entries = self.paginator.page(self.page_number)
serialized_data = {} serialized_data = {}
for entry in entries: for entry in requested_entries.object_list:
serialized_data[str(entry.id)] = self._model_to_geo_json(entry) serialized_data[str(entry.id)] = self._model_to_geo_json(entry)
return serialized_data return serialized_data

View File

@ -21,7 +21,6 @@ class AbstractAPIViewV1(AbstractAPIView):
""" Holds general serialization functions for API v1 """ Holds general serialization functions for API v1
""" """
serializer = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.lookup = { self.lookup = {
@ -45,11 +44,17 @@ class AbstractAPIViewV1(AbstractAPIView):
response (JsonResponse) response (JsonResponse)
""" """
try: try:
self.rpp = int(request.GET.get("rpp", self.rpp))
self.page_number = int(request.GET.get("p", self.page_number))
self.serializer.rpp = self.rpp
self.serializer.page_number = self.page_number
self.serializer.prepare_lookup(id, self.user) self.serializer.prepare_lookup(id, self.user)
data = self.serializer.fetch_and_serialize() data = self.serializer.fetch_and_serialize()
except Exception as e: except Exception as e:
return self.return_error_response(e, 500) return self._return_error_response(e, 500)
return JsonResponse(data) return self._return_response(request, data)
def post(self, request: HttpRequest): def post(self, request: HttpRequest):
""" Handles the POST request """ Handles the POST request
@ -67,7 +72,7 @@ class AbstractAPIViewV1(AbstractAPIView):
body = json.loads(body) body = json.loads(body)
created_id = self.serializer.create_model_from_json(body, self.user) created_id = self.serializer.create_model_from_json(body, self.user)
except Exception as e: except Exception as e:
return self.return_error_response(e, 500) return self._return_error_response(e, 500)
return JsonResponse({"id": created_id}) return JsonResponse({"id": created_id})
def put(self, request: HttpRequest, id=None): def put(self, request: HttpRequest, id=None):
@ -87,7 +92,7 @@ class AbstractAPIViewV1(AbstractAPIView):
body = json.loads(body) body = json.loads(body)
updated_id = self.serializer.update_model_from_json(id, body, self.user) updated_id = self.serializer.update_model_from_json(id, body, self.user)
except Exception as e: except Exception as e:
return self.return_error_response(e, 500) return self._return_error_response(e, 500)
return JsonResponse({"id": updated_id}) return JsonResponse({"id": updated_id})
def delete(self, request: HttpRequest, id=None): def delete(self, request: HttpRequest, id=None):
@ -104,7 +109,7 @@ class AbstractAPIViewV1(AbstractAPIView):
try: try:
success = self.serializer.delete_entry(id, self.user) success = self.serializer.delete_entry(id, self.user)
except Exception as e: except Exception as e:
return self.return_error_response(e, 500) return self._return_error_response(e, 500)
return JsonResponse( return JsonResponse(
{ {
"success": success, "success": success,

View File

@ -31,10 +31,22 @@ class AbstractAPIView(View):
""" """
user = None user = None
serializer = None
rpp = 5 # Results per page default
page_number = 1 # Page number default
class Meta: class Meta:
abstract = True abstract = True
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.response_body_base = {
"rpp": None,
"p": None,
"next": None,
"results": None
}
@csrf_exempt @csrf_exempt
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
try: try:
@ -42,13 +54,14 @@ class AbstractAPIView(View):
ksp_token = request.headers.get(KSP_TOKEN_HEADER_IDENTIFIER, None) ksp_token = request.headers.get(KSP_TOKEN_HEADER_IDENTIFIER, None)
ksp_user = request.headers.get(KSP_USER_HEADER_IDENTIFIER, None) ksp_user = request.headers.get(KSP_USER_HEADER_IDENTIFIER, None)
self.user = APIUserToken.get_user_from_token(ksp_token, ksp_user) self.user = APIUserToken.get_user_from_token(ksp_token, ksp_user)
request.user = self.user
if not self.user.is_default_user(): if not self.user.is_default_user():
raise PermissionError("Default permissions required") raise PermissionError("Default permissions required")
except PermissionError as e: except PermissionError as e:
return self.return_error_response(e, 403) return self._return_error_response(e, 403)
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
def return_error_response(self, error, status_code=500): def _return_error_response(self, error, status_code=500):
""" Returns an error as JsonReponse """ Returns an error as JsonReponse
Args: Args:
@ -68,6 +81,31 @@ class AbstractAPIView(View):
status=status_code status=status_code
) )
def _return_response(self, request: HttpRequest, data):
""" Returns all important data into a response object
Args:
request (HttpRequest): The incoming request
data (dict): The serialized data
Returns:
response (JsonResponse): The response to be returned
"""
response = self.response_body_base
next_page = self.page_number + 1
next_page = next_page if next_page in self.serializer.paginator.page_range else None
if next_page is not None:
next_url = request.build_absolute_uri(
request.path + f"?rpp={self.rpp}&p={next_page}"
)
else:
next_url = None
response["rpp"] = self.rpp
response["p"] = self.page_number
response["next"] = next_url
response["results"] = data
return JsonResponse(response)
class InterventionCheckAPIView(AbstractAPIView): class InterventionCheckAPIView(AbstractAPIView):
@ -82,14 +120,14 @@ class InterventionCheckAPIView(AbstractAPIView):
response (JsonResponse) response (JsonResponse)
""" """
if not self.user.is_zb_user(): if not self.user.is_zb_user():
return self.return_error_response("Permission not granted", 403) return self._return_error_response("Permission not granted", 403)
try: try:
obj = Intervention.objects.get( obj = Intervention.objects.get(
id=id, id=id,
users__in=[self.user] users__in=[self.user]
) )
except Exception as e: except Exception as e:
return self.return_error_response(e) return self._return_error_response(e)
all_valid, check_details = self.run_quality_checks(obj) all_valid, check_details = self.run_quality_checks(obj)
@ -161,7 +199,7 @@ class AbstractModelShareAPIView(AbstractAPIView):
try: try:
users = self._get_shared_users_of_object(id) users = self._get_shared_users_of_object(id)
except Exception as e: except Exception as e:
return self.return_error_response(e) return self._return_error_response(e)
data = { data = {
"users": [ "users": [
@ -185,7 +223,7 @@ class AbstractModelShareAPIView(AbstractAPIView):
try: try:
success = self._process_put_body(request.body, id) success = self._process_put_body(request.body, id)
except Exception as e: except Exception as e:
return self.return_error_response(e) return self._return_error_response(e)
data = { data = {
"success": success, "success": success,
} }