#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
This commit is contained in:
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…
Reference in New Issue
Block a user