#31 API basic implementation Cleanup

* cleans code
* reworks many code fragments into smaller methods and split into super class
This commit is contained in:
mpeltriaux 2022-01-21 18:34:01 +01:00
parent 870cc96a1a
commit 8d400b4ffe
6 changed files with 206 additions and 128 deletions

View File

@ -5,25 +5,19 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 21.01.22 Created on: 21.01.22
""" """
import json
from django.http import HttpRequest, JsonResponse from api.views.v1.views import AbstractModelAPIViewV1
from api.views.v1.general import AbstractModelAPIViewV1
from compensation.models import Compensation from compensation.models import Compensation
class APICompensationViewV1(AbstractModelAPIViewV1): class APICompensationViewV1(AbstractModelAPIViewV1):
model = Compensation model = Compensation
def get(self, request: HttpRequest, id): def prepare_lookup(self, id):
self.lookup["id"] = id self.lookup["id"] = id
del self.lookup["users__in"] del self.lookup["users__in"]
self.lookup["intervention__users__in"] = [self.user] self.lookup["intervention__users__in"] = [self.user]
data = self.fetch_and_serialize()
return JsonResponse(data)
def intervention_to_json(self, entry): def intervention_to_json(self, entry):
return { return {
"id": entry.pk, "id": entry.pk,
@ -31,21 +25,12 @@ class APICompensationViewV1(AbstractModelAPIViewV1):
"title": entry.title, "title": entry.title,
} }
def model_to_json(self, entry): def extend_properties_data(self, entry):
entry_json = { self.properties_data["is_cef"] = entry.is_cef
"identifier": entry.identifier, self.properties_data["is_coherence_keeping"] = entry.is_coherence_keeping
"title": entry.title, self.properties_data["intervention"] = self.intervention_to_json(entry.intervention)
"is_cef": entry.is_cef, self.properties_data["before_states"] = self.compensation_state_to_json(entry.before_states.all())
"is_coherence_keeping": entry.is_coherence_keeping, self.properties_data["after_states"] = self.compensation_state_to_json(entry.after_states.all())
"intervention": self.intervention_to_json(entry.intervention), self.properties_data["actions"] = self.compensation_actions_to_json(entry.actions.all())
"before_states": self.compensation_state_to_json(entry.before_states.all()), self.properties_data["deadlines"] = self.deadlines_to_json(entry.deadlines.all())
"after_states": self.compensation_state_to_json(entry.after_states.all()),
"actions": self.compensation_actions_to_json(entry.actions.all()),
"deadlines": self.deadlines_to_json(entry.deadlines.all()),
"modified_on": self.modified_on_to_json(entry),
"created_on": self.created_on_to_json(entry),
}
geom = entry.geometry.geom.geojson
geo_json = json.loads(geom)
geo_json["properties"] = entry_json
return geo_json

View File

@ -5,11 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 21.01.22 Created on: 21.01.22
""" """
import json from api.views.v1.views import AbstractModelAPIViewV1
from django.http import JsonResponse, HttpRequest
from api.views.v1.general import AbstractModelAPIViewV1
from compensation.models import EcoAccount from compensation.models import EcoAccount
from intervention.models import Legal, Responsibility from intervention.models import Legal, Responsibility
@ -17,33 +13,16 @@ from intervention.models import Legal, Responsibility
class APIEcoAccountViewV1(AbstractModelAPIViewV1): class APIEcoAccountViewV1(AbstractModelAPIViewV1):
model = EcoAccount model = EcoAccount
def get(self, request: HttpRequest, id): def extend_properties_data(self, entry):
self.lookup["id"] = id self.properties_data["deductable_surface"] = entry.deductable_surface
self.lookup["users__in"] = [self.user] self.properties_data["deductable_surface_available"] = entry.deductable_surface - entry.get_deductions_surface()
self.properties_data["responsible"] = self.responsible_to_json(entry.responsible)
data = self.fetch_and_serialize() self.properties_data["legal"] = self.legal_to_json(entry.legal)
return JsonResponse(data) self.properties_data["before_states"] = self.compensation_state_to_json(entry.before_states.all())
self.properties_data["after_states"] = self.compensation_state_to_json(entry.after_states.all())
def model_to_json(self, entry): self.properties_data["actions"] = self.compensation_actions_to_json(entry.actions.all())
entry_json = { self.properties_data["deadlines"] = self.deadlines_to_json(entry.deadlines.all())
"identifier": entry.identifier, self.properties_data["deductions"] = self.deductions_to_json(entry.deductions.all())
"title": entry.title,
"deductable_surface": entry.deductable_surface,
"deductable_surface_available": entry.deductable_surface - entry.get_deductions_surface(),
"responsible": self.responsible_to_json(entry.responsible),
"legal": self.legal_to_json(entry.legal),
"before_states": self.compensation_state_to_json(entry.before_states.all()),
"after_states": self.compensation_state_to_json(entry.after_states.all()),
"actions": self.compensation_actions_to_json(entry.actions.all()),
"deadlines": self.deadlines_to_json(entry.deadlines.all()),
"deductions": self.deductions_to_json(entry.deductions.all()),
"modified_on": self.modified_on_to_json(entry),
"created_on": self.created_on_to_json(entry),
}
geom = entry.geometry.geom.geojson
geo_json = json.loads(geom)
geo_json["properties"] = entry_json
return geo_json
def legal_to_json(self, legal: Legal): def legal_to_json(self, legal: Legal):
return { return {

View File

@ -5,37 +5,24 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 21.01.22 Created on: 21.01.22
""" """
import json from api.views.v1.views import AbstractModelAPIViewV1
from django.http import JsonResponse, HttpRequest
from api.views.v1.ecoaccount import APIEcoAccountViewV1
from ema.models import Ema from ema.models import Ema
from intervention.models import Responsibility
class APIEmaViewV1(APIEcoAccountViewV1): class APIEmaViewV1(AbstractModelAPIViewV1):
model = Ema model = Ema
def get(self, request: HttpRequest, id): def responsible_to_json(self, responsible: Responsibility):
self.lookup["id"] = id return {
self.lookup["users__in"] = [self.user] "conservation_office": self.konova_code_to_json(responsible.conservation_office),
"conservation_file_number": responsible.conservation_file_number,
data = self.fetch_and_serialize() "handler": responsible.handler,
return JsonResponse(data)
def model_to_json(self, entry):
entry_json = {
"identifier": entry.identifier,
"title": entry.title,
"responsible": self.responsible_to_json(entry.responsible),
"before_states": self.compensation_state_to_json(entry.before_states.all()),
"after_states": self.compensation_state_to_json(entry.after_states.all()),
"actions": self.compensation_actions_to_json(entry.actions.all()),
"deadlines": self.deadlines_to_json(entry.deadlines.all()),
"modified_on": self.modified_on_to_json(entry),
"created_on": self.created_on_to_json(entry),
} }
geom = entry.geometry.geom.geojson
geo_json = json.loads(geom) def extend_properties_data(self, entry):
geo_json["properties"] = entry_json self.properties_data["responsible"] = self.responsible_to_json(entry.responsible)
return geo_json self.properties_data["before_states"] = self.compensation_state_to_json(entry.before_states.all())
self.properties_data["after_states"] = self.compensation_state_to_json(entry.after_states.all())
self.properties_data["actions"] = self.compensation_actions_to_json(entry.actions.all())
self.properties_data["deadlines"] = self.deadlines_to_json(entry.deadlines.all())

View File

@ -5,25 +5,15 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 21.01.22 Created on: 21.01.22
""" """
import json
from django.db.models import QuerySet from django.db.models import QuerySet
from django.http import HttpRequest, JsonResponse
from api.views.v1.general import AbstractModelAPIViewV1 from api.views.v1.views import AbstractModelAPIViewV1
from intervention.models import Intervention from intervention.models import Intervention
class APIInterventionViewV1(AbstractModelAPIViewV1): class APIInterventionViewV1(AbstractModelAPIViewV1):
model = Intervention model = Intervention
def get(self, request: HttpRequest, id):
self.lookup["id"] = id
self.lookup["users__in"] = [self.user]
data = self.fetch_and_serialize()
return JsonResponse(data)
def compensations_to_json(self, qs: QuerySet): def compensations_to_json(self, qs: QuerySet):
return list( return list(
qs.values( qs.values(
@ -31,19 +21,9 @@ class APIInterventionViewV1(AbstractModelAPIViewV1):
) )
) )
def model_to_json(self, entry: Intervention): def extend_properties_data(self, entry):
entry_json = { self.properties_data["responsible"] = self.responsible_to_json(entry.responsible)
"identifier": entry.identifier, self.properties_data["legal"] = self.legal_to_json(entry.legal)
"title": entry.title, self.properties_data["compensations"] = self.compensations_to_json(entry.compensations.all())
"responsible": self.responsible_to_json(entry.responsible), self.properties_data["payments"] = self.payments_to_json(entry.payments.all())
"legal": self.legal_to_json(entry.legal), self.properties_data["deductions"] = self.deductions_to_json(entry.deductions.all())
"compensations": self.compensations_to_json(entry.compensations.all()),
"payments": self.payments_to_json(entry.payments.all()),
"deductions": self.deductions_to_json(entry.deductions.all()),
"modified_on": self.modified_on_to_json(entry),
"created_on": self.created_on_to_json(entry),
}
geom = entry.geometry.geom.geojson
geo_json = json.loads(geom)
geo_json["properties"] = entry_json
return geo_json

View File

@ -5,7 +5,10 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 21.01.22 Created on: 21.01.22
""" """
import json
from django.db.models import QuerySet from django.db.models import QuerySet
from django.http import JsonResponse, HttpRequest
from api.views.views import AbstractModelAPIView from api.views.views import AbstractModelAPIView
from codelist.models import KonovaCode from codelist.models import KonovaCode
@ -17,7 +20,69 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
""" """
def get(self, request: HttpRequest, id):
""" Handles the GET request
Performs the fetching and serialization of the data
Args:
request (HttpRequest): The incoming request
id (str): The entries id
Returns:
"""
self.prepare_lookup(id)
try:
data = self.fetch_and_serialize()
except Exception as e:
return self.return_error_response(e, 500)
return JsonResponse(data)
def model_to_geo_json(self, entry):
""" Adds the basic data, which all elements hold
Args:
entry (): The data entry
Returns:
"""
geom = entry.geometry.geom.geojson
geo_json = json.loads(geom)
self.properties_data = {
"id": entry.id,
"identifier": entry.identifier,
"title": entry.title,
"created_on": self.created_on_to_json(entry),
"modified_on": self.modified_on_to_json(entry),
}
self.extend_properties_data(entry)
geo_json["properties"] = self.properties_data
return geo_json
def prepare_lookup(self, id):
""" Customizes lookup values for db filtering
Args:
id (str): The entries id
Returns:
"""
self.lookup["id"] = id
self.lookup["users__in"] = [self.user]
def konova_code_to_json(self, konova_code: KonovaCode): def konova_code_to_json(self, konova_code: KonovaCode):
""" Serializes KonovaCode model into json
Args:
konova_code (KonovaCode): The KonovaCode entry
Returns:
serialized_json (dict)
"""
return { return {
"atom_id": konova_code.atom_id, "atom_id": konova_code.atom_id,
"long_name": konova_code.long_name, "long_name": konova_code.long_name,
@ -25,6 +90,14 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
} }
def responsible_to_json(self, responsible: Responsibility): def responsible_to_json(self, responsible: Responsibility):
""" Serializes Responsibility model into json
Args:
responsible (Responsibility): The Responsibility entry
Returns:
serialized_json (dict)
"""
return { return {
"registration_office": self.konova_code_to_json(responsible.registration_office), "registration_office": self.konova_code_to_json(responsible.registration_office),
"registration_file_number": responsible.registration_file_number, "registration_file_number": responsible.registration_file_number,
@ -34,6 +107,14 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
} }
def legal_to_json(self, legal: Legal): def legal_to_json(self, legal: Legal):
""" Serializes Legal model into json
Args:
legal (Legal): The Legal entry
Returns:
serialized_json (dict)
"""
return { return {
"registration_date": legal.registration_date, "registration_date": legal.registration_date,
"binding_date": legal.binding_date, "binding_date": legal.binding_date,
@ -48,7 +129,7 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
qs (QuerySet): A queryset of Payment entries qs (QuerySet): A queryset of Payment entries
Returns: Returns:
serialized_json (list)
""" """
return list(qs.values("amount", "due_on", "comment")) return list(qs.values("amount", "due_on", "comment"))
@ -59,7 +140,7 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
qs (QuerySet): A queryset of EcoAccountDeduction entries qs (QuerySet): A queryset of EcoAccountDeduction entries
Returns: Returns:
serialized_json (list)
""" """
return [ return [
{ {
@ -80,6 +161,14 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
] ]
def compensation_state_to_json(self, qs: QuerySet): def compensation_state_to_json(self, qs: QuerySet):
""" Serializes compensation states into json
Args:
qs (QuerySet): A queryset of CompensationState entries
Returns:
serialized_json (list)
"""
return [ return [
{ {
"biotope": self.konova_code_to_json(entry.biotope_type), "biotope": self.konova_code_to_json(entry.biotope_type),
@ -89,6 +178,14 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
] ]
def compensation_actions_to_json(self, qs: QuerySet): def compensation_actions_to_json(self, qs: QuerySet):
""" Serializes CompensationActions into json
Args:
qs (QuerySet): A queryset of CompensationAction entries
Returns:
serialized_json (list)
"""
return [ return [
{ {
"action": self.konova_code_to_json(entry.action_type), "action": self.konova_code_to_json(entry.action_type),
@ -100,6 +197,14 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
] ]
def deadlines_to_json(self, qs: QuerySet): def deadlines_to_json(self, qs: QuerySet):
""" Serializes deadlines into json
Args:
qs (QuerySet): A queryset of Deadline entries
Returns:
serialized_json (list)
"""
return list(qs.values( return list(qs.values(
"type", "type",
"date", "date",
@ -107,9 +212,25 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
)) ))
def created_on_to_json(self, entry): def created_on_to_json(self, entry):
""" Serializes the created_on into json
Args:
entry (BaseObject): The entry
Returns:
created_on (timestamp)
"""
return entry.created.timestamp return entry.created.timestamp
def modified_on_to_json(self, entry): def modified_on_to_json(self, entry):
""" Serializes the modified_on into json
Args:
entry (BaseObject): The entry
Returns:
modified_on (timestamp)
"""
modified_on = entry.modified or entry.created modified_on = entry.modified or entry.created
modified_on = modified_on.timestamp modified_on = modified_on.timestamp
return modified_on return modified_on

View File

@ -25,6 +25,7 @@ class AbstractModelAPIView(View):
model = None model = None
user = None user = None
lookup = None lookup = None
properties_data = None
class Meta: class Meta:
abstract = True abstract = True
@ -38,8 +39,20 @@ class AbstractModelAPIView(View):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@abstractmethod @abstractmethod
def model_to_json(self, entry): def model_to_geo_json(self, entry):
""" Defines the returned json values of the model """ Defines the model as geo json
Args:
entry (): The found entry from the database
Returns:
"""
raise NotImplementedError("Must be implemented in subclasses")
@abstractmethod
def extend_properties_data(self, entry):
""" Defines the 'properties' part of geo json
Args: Args:
entry (): The found entry from the database entry (): The found entry from the database
@ -57,20 +70,33 @@ class AbstractModelAPIView(View):
Returns: Returns:
serialized_data (dict) serialized_data (dict)
""" """
qs = self.model.objects.filter(**self.lookup) entry = self.model.objects.get(**self.lookup)
serialized_data = {} serialized_data = self.model_to_geo_json(entry)
for entry in qs:
serialized_data[str(entry.pk)] = self.model_to_json(entry)
return serialized_data return serialized_data
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
try: try:
self.user = APIUserToken.get_user_from_token(request.headers.get(KSP_TOKEN_HEADER_IDENTIFIER, None)) self.user = APIUserToken.get_user_from_token(request.headers.get(KSP_TOKEN_HEADER_IDENTIFIER, None))
except PermissionError as e: except PermissionError as e:
return JsonResponse( return self.return_error_response(e, 403)
{
"error": e.__str__()
},
status=403
)
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
def return_error_response(self, error, status_code=500):
""" Returns an error as JsonReponse
Args:
error (): The error/exception
status_code (): The desired status code
Returns:
"""
content = [error.__str__()]
if hasattr(error, "messages"):
content = error.messages
return JsonResponse(
{
"errors": content
},
status=status_code
)