Closed
Description
It appears that the JSON renderer expects every serializer to be a ModelSerializer
, preventing regular Serializer
use without a model.
Reproduction:
from typing import TYPE_CHECKING
from rest_framework.permissions import AllowAny
from rest_framework.fields import CharField, Field
from rest_framework.views import Response
from rest_framework.viewsets import GenericViewSet
from rest_framework_json_api.serializers import Serializer
from .serializers import HealthStatusSerializer
if TYPE_CHECKING:
from rest_framework. request import Request
class HealthStatusSerializer(Serializer):
"""The health status of all services"""
def get_fields(self) -> dict[str, Field]:
return {"Database: default": CharField()} # for demo purposes - usually populate from installed health checks
class Meta:
resource_name = "HealthStatus"
class HealthStatusAPIView(GenericViewSet):
"""A health status view"""
serializer = HealthStatusSerializer
permission_clases = [AllowAny]
pagination_class = None # remove pagination
filter_backends = [] # remove default filters
def retrieve(request: Request, **kwargs) -> Response:
"""Retrieves the health status of all services"""
errors: bool = False # for demo purposes - usually check status of installed health checks
return Response(
self.get_serializer({"Database: default": "working"}).data,
status_code=200 if not errors else 500,
)
Stacktrace:
Traceback (most recent call last):
File ".../django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File ".../django/core/handlers/base.py", line 220, in _get_response
response = response.render()
File ".../django/template/response.py", line 114, in render
self. content = self.rendered_content
File ".../rest_framework/response.py", line 70, in rendered_content
ret = renderer. data, accepted_media_type, context)
File ".../rest_framework_json_api/renderers.py", line 602, in render
json_api_data = self.build_json_resource_obj(
File ".../rest_framework_json_api/renderers.py", line 464, in build_json_resource_obj
encoding. force_str(resource_instance.pk) if resource_instance else None,
AttributeError: 'dict' object has no attribute 'pk'
Suspected code:
django-rest-framework-json-api/rest_framework_json_api/renderers.py
Lines 460 to 467 in 735ce29
Suggestion:
resource_data = [
("type", resource_name),
(
"id",
- encoding.force_str(resource_instance.pk) if resource_instance else None,
+ encoding.force_str(resource_instance.pk) if hasattr(resource_instance, "pk") else None,
),
("attributes", cls.extract_attributes(fields, resource)),
]