#31 API DELETE

* adds support for DELETE method for all relevant objects
* improves get_obj_from_db functionality
* drops custom compensation logic for get_obj_from_db due to improvement of base method
pull/90/head
mpeltriaux 3 years ago
parent 5a7ea0b6c2
commit e7dbea49cd

@ -11,6 +11,8 @@ 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 konova.utils.message_templates import DATA_UNSHARED
class AbstractModelAPISerializer: class AbstractModelAPISerializer:
model = None model = None
@ -66,7 +68,7 @@ class AbstractModelAPISerializer:
# Return all objects # Return all objects
del self.lookup["id"] del self.lookup["id"]
else: else:
# Return certain objects # Return certain object
self.lookup["id"] = _id self.lookup["id"] = _id
self.lookup["users__in"] = [user] self.lookup["users__in"] = [user]
@ -139,10 +141,14 @@ class AbstractModelAPISerializer:
Returns: Returns:
""" """
return self.model.objects.get( obj = self.model.objects.get(
id=id, id=id,
users__in=[user] deleted__isnull=True,
) )
is_shared = obj.is_shared_with(user)
if not is_shared:
raise PermissionError(DATA_UNSHARED)
return obj
@abstractmethod @abstractmethod
def initialize_objects(self, json_model, user): def initialize_objects(self, json_model, user):

@ -129,23 +129,6 @@ class CompensationAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensa
return obj.id return obj.id
def get_obj_from_db(self, id, user):
""" Returns the object from database
Fails if id not found or user does not have shared access
Args:
id (str): The object's id
user (User): The API user
Returns:
"""
return self.model.objects.get(
id=id,
intervention__users__in=[user]
)
def update_model_from_json(self, id, json_model, user): def update_model_from_json(self, id, json_model, user):
""" Updates an entry for the model based on the contents of json_model """ Updates an entry for the model based on the contents of json_model

@ -17,6 +17,7 @@ from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES
from compensation.models import CompensationAction, UnitChoices, CompensationState from compensation.models import CompensationAction, UnitChoices, CompensationState
from intervention.models import Responsibility, Legal from intervention.models import Responsibility, Legal
from konova.models import Deadline, DeadlineType from konova.models import Deadline, DeadlineType
from konova.utils.message_templates import DATA_UNSHARED
class AbstractModelAPISerializerV1(AbstractModelAPISerializer): class AbstractModelAPISerializerV1(AbstractModelAPISerializer):
@ -101,6 +102,27 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer):
modified_on = modified_on.timestamp if modified_on is not None else None modified_on = modified_on.timestamp if modified_on is not None else None
return modified_on return modified_on
def delete_entry(self, id, user):
""" Marks an entry as deleted
Args:
id (str): The entry's id
user (User): The API user
Returns:
"""
entry = self.get_obj_from_db(id, user)
is_shared = entry.is_shared_with(user)
if not is_shared:
raise PermissionError(DATA_UNSHARED)
# Do not send mails if entry is deleting using API. THere could be hundreds of deletion resulting in hundreds of
# mails at once.
entry.mark_as_deleted(user, send_mail=False)
entry.refresh_from_db()
success = entry.deleted is not None
return success
class DeductableAPISerializerV1Mixin: class DeductableAPISerializerV1Mixin:
class Meta: class Meta:

@ -79,7 +79,7 @@ class AbstractAPIViewV1(AbstractAPIView):
id (str): The entries id id (str): The entries id
Returns: Returns:
response (JsonResponse)
""" """
try: try:
body = request.body.decode("utf-8") body = request.body.decode("utf-8")
@ -89,6 +89,27 @@ class AbstractAPIViewV1(AbstractAPIView):
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):
""" Handles a DELETE request
Args:
request (HttpRequest): The incoming request
id (str): The object's id
Returns:
response (JsonResponse)
"""
try:
success = self.serializer.delete_entry(id, self.user)
except Exception as e:
return self.return_error_response(e, 500)
return JsonResponse(
{
"success": success,
}
)
class InterventionAPIViewV1(AbstractAPIViewV1): class InterventionAPIViewV1(AbstractAPIViewV1):
serializer = InterventionAPISerializerV1 serializer = InterventionAPISerializerV1

@ -104,7 +104,7 @@ class BaseObject(BaseResource):
def set_status_messages(self, request: HttpRequest): def set_status_messages(self, request: HttpRequest):
raise NotImplementedError raise NotImplementedError
def mark_as_deleted(self, user: User): def mark_as_deleted(self, user: User, send_mail: bool = True):
""" Mark an entry as deleted """ Mark an entry as deleted
Does not delete from database but sets a timestamp for being deleted on and which user deleted the object Does not delete from database but sets a timestamp for being deleted on and which user deleted the object
@ -124,10 +124,11 @@ class BaseObject(BaseResource):
self.deleted = action self.deleted = action
self.log.add(action) self.log.add(action)
# Send mail if send_mail:
shared_users = self.shared_users.values_list("id", flat=True) # Send mail
for user_id in shared_users: shared_users = self.shared_users.values_list("id", flat=True)
celery_send_mail_shared_data_deleted.delay(self.identifier, user_id) for user_id in shared_users:
celery_send_mail_shared_data_deleted.delay(self.identifier, user_id)
self.save() self.save()

Loading…
Cancel
Save