feat(api): Always use a models View serializer for the response

ref: #477 #579 closes #578
This commit is contained in:
2025-02-11 19:44:27 +09:30
parent 2e0b835af9
commit 16388f0a10
2 changed files with 92 additions and 0 deletions

View File

@ -1,3 +1,4 @@
import importlib
from django.utils.safestring import mark_safe
from rest_framework import viewsets
@ -41,6 +42,29 @@ class Create(
response = super().create(request = request, *args, **kwargs)
# Always return using the ViewSerializer
serializer_module = importlib.import_module(self.serializer_class.__module__)
view_serializer = getattr(serializer_module, self.get_view_serializer_name())
serializer = view_serializer(
self.get_queryset().get( pk = int(response.data['id']) ),
context = {
'request': request,
'view': self,
},
)
# Mimic ALL details from DRF response except serializer
response = Response(
data = serializer.data,
status = response.status_code,
template_name = response.template_name,
headers = response.headers,
exception = response.exception,
content_type = response.content_type,
)
except Exception as e:
if not isinstance(e, APIException):
@ -246,6 +270,29 @@ class Update(
response = super().partial_update(request = request, *args, **kwargs)
# Always return using the ViewSerializer
serializer_module = importlib.import_module(self.serializer_class.__module__)
view_serializer = getattr(serializer_module, self.get_view_serializer_name())
serializer = view_serializer(
self.queryset.get( pk = int(self.kwargs['pk']) ),
context = {
'request': request,
'view': self,
},
)
# Mimic ALL details from DRF response except serializer
response = Response(
data = serializer.data,
status = response.status_code,
template_name = response.template_name,
headers = response.headers,
exception = response.exception,
content_type = response.content_type,
)
except Exception as e:
if not isinstance(e, APIException):
@ -290,6 +337,29 @@ class Update(
response = super().update(request = request, *args, **kwargs)
# Always return using the ViewSerializer
serializer_module = importlib.import_module(self.serializer_class.__module__)
view_serializer = getattr(serializer_module, self.get_view_serializer_name())
serializer = view_serializer(
self.queryset.get( pk = int(self.kwargs['pk']) ),
context = {
'request': request,
'view': self,
},
)
# Mimic ALL details from DRF response except serializer
response = Response(
data = serializer.data,
status = response.status_code,
template_name = response.template_name,
headers = response.headers,
exception = response.exception,
content_type = response.content_type,
)
except Exception as e:
if not isinstance(e, APIException):
@ -575,6 +645,9 @@ class ModelViewSetBase(
If not used, use get_serializer_class function and cache the class here.
"""
view_serializer_name: str = None
"""Cached model view Serializer name"""
def get_queryset(self):
@ -618,6 +691,23 @@ class ModelViewSetBase(
def get_view_serializer_name(self) -> str:
"""Get the Models `View` Serializer name.
Override this function if required and/or the serializer names deviate from default.
Returns:
str: Models View Serializer Class name
"""
if self.view_serializer_name is None:
self.view_serializer_name = self.serializer_class.__name__.replace('ModelSerializer', 'ViewSerializer')
return self.view_serializer_name
class ModelViewSet(
ModelViewSetBase,
Create,

View File

@ -301,6 +301,8 @@ if API_ENABLED:
Centurion ERP's API is versioned, with [v1 Depreciated](/api/swagger) and [v2 as the current](/api/v2/docs).
For CRUD actions `Add`, `update` and `replace` the serializer that returns is the Models `View` serializer.
**Note:** _API v2 is currently in beta phase. AS such is subject to change. When the new UI ius released, API v2 will move to stable._
## Authentication