{"record":{"id":"a6e930f229f44905","repo":"django/django","slug":"subclasses-of-serializer-must-provide-a-start-obje","errorCode":null,"errorMessage":"subclasses of Serializer must provide a start_object() method","messagePattern":"subclasses of Serializer must provide a start_object\\(\\) method","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"django/core/serializers/base.py","lineNumber":170,"sourceCode":"    def start_serialization(self):\n        \"\"\"\n        Called when serializing of the queryset starts.\n        \"\"\"\n        raise NotImplementedError(\n            \"subclasses of Serializer must provide a start_serialization() method\"\n        )\n\n    def end_serialization(self):\n        \"\"\"\n        Called when serializing of the queryset ends.\n        \"\"\"\n        pass\n\n    def start_object(self, obj):\n        \"\"\"\n        Called when serializing of an object starts.\n        \"\"\"\n        raise NotImplementedError(\n            \"subclasses of Serializer must provide a start_object() method\"\n        )\n\n    def end_object(self, obj):\n        \"\"\"\n        Called when serializing of an object ends.\n        \"\"\"\n        pass\n\n    def handle_field(self, obj, field):\n        \"\"\"\n        Called to handle each individual (non-relational) field on an object.\n        \"\"\"\n        raise NotImplementedError(\n            \"subclasses of Serializer must provide a handle_field() method\"\n        )\n\n    def handle_fk_field(self, obj, field):","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/django/django/blob/b5388a3a80cafcce2e34196d8e81cf5b48eb33bb/django/core/serializers/base.py#L152-L188","documentation":"`Serializer.start_object()` is an abstract hook in Django's serializer template-method framework (django/core/serializers/base.py:166). It is invoked once per object at the start of serialization (base.py:110); the base class raises NotImplementedError to force subclasses to provide concrete behavior. Hitting it means a custom Serializer subclass did not override this required method.","triggerScenarios":"Calling `my_serializer.serialize(queryset)` on an instance of a class that subclasses `django.core.serializers.base.Serializer` directly (not PythonSerializer) and omits a `start_object(self, obj)` definition. The NotImplementedError fires on the first object in the queryset before any field is processed.","commonSituations":"Writing a custom serializer backend for a new format (CSV, MessagePack, XML variants) and forgetting one of the six required hooks; copy-pasting an existing serializer and deleting methods; upgrading Django and refactoring a third-party serializer (e.g. django-rest-framework's serializer bridge) that dropped the override.","solutions":["Implement `def start_object(self, obj):` in your subclass to emit whatever per-object framing your format needs.","Subclass a concrete serializer (`django.core.serializers.python.Serializer`) instead of `base.Serializer` so all six hooks are inherited, then override only what differs.","Verify all six required hooks exist: `start_serialization`, `start_object`, `end_object`, `handle_field`, `handle_fk_field`, `handle_m2m_field`."],"exampleFix":"// before\nclass CsvSerializer(base.Serializer):\n    def start_serialization(self):\n        self.stream.write('model,pk,field,value\\n')\n    # missing start_object -> NotImplementedError at base.py:170\n// after\nclass CsvSerializer(base.Serializer):\n    def start_serialization(self):\n        self.stream.write('model,pk,field,value\\n')\n    def start_object(self, obj):\n        self._current_obj = obj\n    def end_object(self, obj):\n        self._current_obj = None","handlingStrategy":"validation","validationCode":"from django.core.serializers.base import Serializer\nREQUIRED = ('start_serialization', 'start_object', 'end_object',\n           'handle_field', 'handle_fk_field', 'handle_m2m_field')\nmissing = [m for m in REQUIRED if not callable(getattr(MySerializer, m, None))]\nassert not missing, f'MySerializer missing overrides: {missing}'","typeGuard":"def is_complete_serializer(cls) -> bool:\n    return (issubclass(cls, Serializer) and\n            all(callable(getattr(cls, m, None))\n                for m in ('start_object', 'handle_field',\n                          'handle_fk_field', 'handle_m2m_field')))","tryCatchPattern":null,"preventionTips":["Subclass python.Serializer (which implements all hooks) and override only what you need.","Add a smoke test that serializes a model exercising plain, FK, and M2M fields.","Lint for NotImplementedError-raising base methods when authoring a subclass."],"tags":["serializers","notimplementederror","subclassing","template-method"],"backgroundTag":null,"analyzedSha":"b5388a3a80cafcce2e34196d8e81cf5b48eb33bb","analyzedAt":"2026-08-10T17:37:52.993Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}