Concept
Serializer first¶
Your serializer is the single place where you describe a resource. Everything else is built from it.
flowchart LR
S["Serializer<br/>(Schemas, validators, hooks)"] --> V["Viewset<br/>REST endpoints"]
S --> P["Python API<br/>create(), get(), model_dump()..."]
S --> D["OpenAPI docs"]
S --> A["Admin, MCP tools"]
One description, many uses¶
The Schemas class, the validators and the hooks you write on a serializer
are used by:
- The viewset, for the
POST,GET,PATCHandDELETEendpoints. - The Python methods, like
Article.create()orArticle.amodel_dump(). - The OpenAPI schema and the interactive docs.
- Integrations such as the Django admin and MCP tools.
So a validator you add to CreateValidators runs for the POST endpoint and
for Article.create() in a script. A hook you add runs for both too.
The viewset is thin¶
A viewset decides how the resource is exposed: URLs, authentication, permissions, filters and pagination. It doesn't decide what is valid or what happens when an object is saved. That lives on the serializer.
Python
@api.viewset(model=Article)
class ArticleViewSet(APIViewSet):
auth = [JWTAuth()]
ordering_fields = ["created_at"]
Two ways to write the serializer¶
| Style | Where it lives |
|---|---|
ModelSerializer |
On the Django model itself |
Serializer |
In a separate class that points to a model with Meta.model |
Both styles have the same Schemas, validators, hooks and Python methods. See
choosing a serializer.