Skip to content

Commit

Permalink
improved json serialization feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Chacoon3 committed Nov 17, 2023
1 parent 07dc333 commit aa56075
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 31 deletions.
17 changes: 8 additions & 9 deletions bmgt435_elp/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from .simulation.Cases import FoodCenter, SimulationException
from .bmgtModels import *
from .utils.statusCode import Status
from .utils.jsonUtils import serialize_models, serialize_model_instance, serialize_simulation_result
from .utils.apiUtils import request_error_handler, password_valid, generic_paginated_query, pager_params_from_request, create_pager_params, AppResponse

import pandas as pd
Expand Down Expand Up @@ -56,7 +55,7 @@ def sign_in(request: HttpRequest) -> AppResponse:
user = BMGTUser.objects.get(did=did, activated=True,)
if check_password(password, user.password):
AuthApi.__set_auth_cookie(resp, user)
resp.resolve(serialize_model_instance(user))
resp.resolve(user)
else:
resp.reject("Sign in failed. Please check your directory ID and password!")
except BMGTUser.DoesNotExist:
Expand Down Expand Up @@ -129,7 +128,7 @@ def me(request: HttpRequest,) -> HttpResponse:
try:
resp = AppResponse()
user = _get_session_user(request)
resp.resolve(serialize_model_instance(user))
resp.resolve(user)
except BMGTUser.DoesNotExist:
resp.reject("User not found!")
except KeyError:
Expand All @@ -148,7 +147,7 @@ def get_group(request: HttpRequest) -> AppResponse:
resp = AppResponse()
group_id = int(request.GET.get('id'))
group = BMGTGroup.objects.get(id=group_id)
resp.resolve(serialize_model_instance(group))
resp.resolve(group)
except BMGTGroup.DoesNotExist:
resp.reject("Group not found!")
except KeyError:
Expand Down Expand Up @@ -185,7 +184,7 @@ def join_group(request: HttpRequest) -> HttpResponse:
if group.users.count() < MAX_GROUP_SIZE:
user.group = group
user.save()
resp.resolve(serialize_model_instance(group))
resp.resolve(group)
else:
resp.reject("Group already full!")
else:
Expand Down Expand Up @@ -231,7 +230,7 @@ def get(request: HttpRequest) -> HttpResponse:
resp = AppResponse()
case_id = request.GET.get('case_id', None)
case = BMGTCase.objects.get( id=case_id, visible=True)
resp.resolve(serialize_model_instance(case))
resp.resolve(case)
except BMGTCase.DoesNotExist:
resp.reject("Case not found!")
except KeyError:
Expand Down Expand Up @@ -311,7 +310,7 @@ def get_case_record(request: HttpRequest) -> HttpResponse:
resp = AppResponse()
case_record_id = request.GET.get('id', None)
case_record = BMGTCaseRecord.objects.get(id=case_record_id, )
resp.resolve(serialize_model_instance(case_record))
resp.resolve(case_record)
except BMGTCaseRecord.DoesNotExist:
resp.reject("Case record not found!")
except KeyError:
Expand Down Expand Up @@ -458,7 +457,7 @@ def create_semester(request: HttpRequest) -> HttpResponse:
with transaction.atomic():
semester = BMGTSemester(year=year, season=season)
semester.save()
resp.resolve(serialize_model_instance(semester))
resp.resolve(semester)
except IntegrityError:
resp.reject("Invalid semester arguments!")

Expand Down Expand Up @@ -489,7 +488,7 @@ def get_semesters(request: HttpRequest) -> HttpResponse:
try:
resp = AppResponse()
semesters = BMGTSemester.objects.all()
resp.resolve(serialize_models(semesters))
resp.resolve(semesters)
except Exception as e:
resp.reject(e)

Expand Down
13 changes: 10 additions & 3 deletions bmgt435_elp/utils/apiUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.core.paginator import Paginator, EmptyPage
from django.http import HttpRequest, HttpResponse
from .statusCode import Status
from .jsonUtils import serialize_paginated_data, serialize_models, CustomJSONEncoder
from .jsonUtils import CustomJSONEncoder
from ..simulation.Cases import SimulationException
from ..bmgtModels import BMGTTransaction

Expand Down Expand Up @@ -145,14 +145,21 @@ def generic_paginated_query(dbModel, pager_params, **kwargs) -> HttpResponse:
obj_set = obj_set.order_by(
pager_params['order'] if pager_params['asc'] else '-'+pager_params['order'])
pager = Paginator(obj_set, pager_params['size'])
page = pager_params['page']

if pager_params['page'] > pager.num_pages or pager_params['page'] < 1:
if page > pager.num_pages or page < 1:
resp.reject("Page not found!")
else:
resp.resolve(serialize_paginated_data(pager, pager_params['page']))
resp.resolve({
"page": page,
"totalPage": pager.num_pages,
"data":pager.page(page).object_list,
})

except EmptyPage:
resp.reject("Page empty!")
except KeyError:
resp.reject("Missing pagination parameters!")

return resp

Expand Down
35 changes: 16 additions & 19 deletions bmgt435_elp/utils/jsonUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,30 @@

class CustomJSONEncoder(json.JSONEncoder):

typeMapper = {
datetime.datetime: lambda obj: obj.astimezone().isoformat(),
np.integer: lambda obj: int(obj),
np.floating: lambda obj: float(obj),
QuerySet: lambda obj: [model.as_dictionary() for model in obj],
list[BMGTModelBase]: lambda obj: [model.as_dictionary() for model in obj],
BMGTModelBase: lambda obj: obj.as_dictionary(),
SimulationResult: lambda obj: obj.iteration_dataframe,
}

def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.astimezone().isoformat()
elif isinstance(obj, np.integer):
return int(obj)
elif isinstance(obj, np.floating):
return float(obj)
else:
return super().default(obj)
objType = type(obj)
if issubclass(objType, BMGTModelBase):
return self.typeMapper[BMGTModelBase](obj)
if self.typeMapper.get(objType, False):
return self.typeMapper[objType](obj)
return super().default(obj)


def serialize_models(querySet:QuerySet | list[BMGTModelBase]) -> str:
return json.dumps([model.as_dictionary() for model in querySet], cls=CustomJSONEncoder)


def serialize_model_instance(instance:BMGTModelBase) -> str:
return json.dumps(instance.as_dictionary(), cls=CustomJSONEncoder)


def serialize_paginated_data(paginator, pageIndex: int) -> str:

return json.dumps({
"page": pageIndex,
"totalPage": paginator.num_pages,
"data": json.loads(serialize_models(paginator.page(pageIndex).object_list)),
})


def serialize_simulation_result(result: SimulationResult) -> str:
return json.dumps(result.iteration_dataframe, cls=CustomJSONEncoder)

0 comments on commit aa56075

Please sign in to comment.