Complete worked example
python
from drf_lab import setup
setup()
import json
from rest_framework import serializers
from rest_framework.decorators import api_view, parser_classes, renderer_classes
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.test import APIRequestFactory
class Input(serializers.Serializer):
slots = serializers.IntegerField(min_value=1, max_value=3)
@api_view(["POST"])
@parser_classes([JSONParser])
@renderer_classes([JSONRenderer])
def endpoint(request):
if request.method == "GET":
return Response({"ready": True})
serializer = Input(data=request.data)
serializer.is_valid(raise_exception=True)
return Response(dict(serializer.validated_data))
def inspect_example(payload):
request = APIRequestFactory().generic(payload.get("method", "POST"), "/accept/",
data=json.dumps(payload.get("body", {"slots": 1})),
content_type=payload.get("type", "application/json"),
HTTP_ACCEPT=payload.get("accept", "application/json"))
response = endpoint(request)
body = {"error": response.data["detail"].code if "detail" in response.data else "validation_error"} if response.status_code >= 400 else dict(response.data)
response.render()
return {"status": response.status_code, "body": body}- Reasoning
- The request factory supplies Accept and Content-Type independently. A supported JSON request reaches the serializer. A client accepting only text/html gets a negotiation failure because the declared renderer is JSON only. An unsupported non-text encoding is rejected instead of being treated as a normal text decoder. The response is rendered before the helper reports its public result. This exercises the framework boundary rather than calling a serializer or handler directly. The helper limits reported error data and never returns a raw exception trace or complete submitted request as a convenience.