skip to content

Serializers

Serializers turn model instances into primitive data and validate incoming payloads back into saved objects, nested relations included. Interviewers probe validation hooks and nested-write cost.

part ofDjango REST Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

19

In Django REST Framework, what is the difference between Serializer and ModelSerializer, and when would you choose a plain Serializer?

level: juniorimportance: must knowfreq 78%

basics

~20 s

A plain Serializer declares every field and needs its own create() and update(); a ModelSerializer builds fields and validators from a model through Meta and implements both methods. Choose a plain Serializer when the payload is not one model.

open as a page

In Django REST Framework, what does serializer.is_valid() do, and what changes when you call it with raise_exception=True?

level: juniorimportance: must knowfreq 72%

basics

~20 s

is_valid() runs the whole validation pipeline on the data passed as data=, stores either validated_data or errors, and returns a boolean. With raise_exception=True an invalid payload raises serializers.ValidationError, which DRF's exception handler turns into a 400 response carrying the errors.

open as a page

In a Django REST Framework ModelSerializer, how do Meta.fields, read_only_fields and extra_kwargs decide which model fields are exposed and writable?

level: middleimportance: must knowfreq 60%

basics

~20 s

Meta.fields (or exclude) chooses which model fields exist on the serializer; read_only_fields marks some as output-only; extra_kwargs passes any other field argument. Both shortcuts apply only to generated fields and are ignored for fields declared explicitly on the class.

open as a page

In Django REST Framework, when do you use validate_<field_name>() versus validate(), and in what order does is_valid() run them?

level: middleimportance: must knowfreq 66%

basics

~20 s

validate_<field_name>(value) checks one field after its own conversion and validators; validate(attrs) checks rules across fields after every field passed and serializer-level validators ran. Both return the value, and a ValidationError in validate() lands under non_field_errors unless given a dict.

open as a page

In Django REST Framework, how do you accept an order with nested line items in one POST, and why does the default ModelSerializer.create() refuse it?

level: seniorimportance: must knowfreq 64%

basics

~20 s

Declare items = LineItemSerializer(many=True) and override create(): pop the items, create the Order, then create each LineItem with order=order. The default ModelSerializer.create() raises an AssertionError on writable nested data because DRF will not guess how to persist it.

open as a page

A Django REST Framework article list endpoint with nested author and tags now runs hundreds of queries per page; how do you find and fix the cause?

level: seniorimportance: must knowfreq 62%

basics

~20 s

Count the queries per request, find the SELECTs repeated per article, map each to the serializer field reading that relation, then load it in get_queryset(): select_related('author'), prefetch_related('tags'), annotate() for counts. Pin the result with a query-count test.

open as a page

In a Django REST Framework generic view, where do select_related() and prefetch_related() go so a nested serializer stops querying per row?

level: juniorimportance: should knowfreq 52%

basics

~20 s

They go on the view's queryset: the queryset class attribute or, usually, an overridden get_queryset(). DRF never optimises queries for you, and the serializer only reads attributes, so the view must load author with select_related() and tags with prefetch_related().

open as a page

In Django REST Framework, how does serializer.save() decide between create() and update(), and what do keyword arguments passed to save() do?

level: juniorimportance: should knowfreq 55%

basics

~10 s

save() calls update(instance, validated_data) when the serializer was built with an instance, and create(validated_data) otherwise. Keyword arguments are merged into validated_data after validation, which is how server-side values such as created_by=request.user reach the model.

open as a page

In a Django REST Framework ModelSerializer, what does Meta.depth do, and why are the nested fields it generates read-only?

level: middleimportance: should knowfreq 42%

basics

~20 s

Meta.depth, from 0 to 10, makes a ModelSerializer render relations as nested objects instead of primary keys, auto-building a nested ModelSerializer with fields 'all' per level. Those generated fields are read_only=True, so clients can no longer set the relation.

open as a page

In Django REST Framework, what do to_representation() and to_internal_value() do, and when is overriding them the right tool?

level: middleimportance: should knowfreq 48%

basics

~20 s

to_representation() turns an object into primitive output for .data; to_internal_value() turns request data into the validated dict during is_valid(). Override them to reshape a representation, usually by calling super() and adjusting, or write a custom Field for a reusable conversion.

open as a page

In Django REST Framework, how does a field's source= argument differ from SerializerMethodField for exposing values the model does not store in a column?

level: middleimportance: should knowfreq 55%

basics

~20 s

source= points a normal field at an attribute path, property, zero-argument method or the whole object, and can be writable. SerializerMethodField is always read-only and calls get_<field_name>(obj) on the serializer, where self.context, such as the request, is available.

open as a page

In Django REST Framework, why does a SerializerMethodField often bring back N+1 queries even after the view prefetches, and how do you fix it?

level: middleimportance: should knowfreq 46%

basics

~20 s

A SerializerMethodField calls get_<field>(obj) once per object, and any ORM query built there runs per row. A filter() on a prefetched relation ignores the prefetch cache. Fix it with annotate() or Prefetch(to_attr=...) in get_queryset(), then read the attribute.

open as a page

In Django REST Framework, what does partial=True change during validation, and why can a PATCH request break cross-field checks in validate()?

level: middleimportance: should knowfreq 52%

basics

~20 s

partial=True makes every field that is absent from the request skip validation entirely: no required error, no default, no validate_<field>(). validate() therefore receives only the sent fields, so cross-field rules must fill the rest from self.instance.

open as a page

In Django REST Framework, how would you write update() for an order serializer whose nested line items clients can add, change or remove?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Override update(): pop the items, save the order's own fields, then match incoming items by id against order.items — update matches, create items without an id, delete ones left out. Declare id as a writable IntegerField, because ModelSerializer's auto id is read-only.

open as a page

In Django REST Framework, what does passing many=True to a serializer actually create, and how do you support bulk create and bulk update?

level: seniorimportance: should knowfreq 36%

basics

~20 s

many=True makes the serializer's new return a ListSerializer wrapping one instance of your class as child. Its create() calls the child's create() per item; update() raises NotImplementedError, so bulk writes need a custom ListSerializer set via Meta.list_serializer_class.

open as a page

Why can two concurrent requests both pass a Django REST Framework UniqueTogetherValidator and still collide, and how do you make the uniqueness guarantee hold?

level: seniorimportance: should knowfreq 46%

basics

~20 s

UniqueValidator and UniqueTogetherValidator only query whether a matching row exists during validation; nothing is locked before the insert. The database unique constraint is the real guarantee, and create() should turn its IntegrityError into a ValidationError instead of a 500.

open as a page

Django REST Framework takes seconds to serialize 5,000 articles although the query count is constant; where does the time go, and what helps?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

The time goes to Python: DRF calls get_attribute() and to_representation() for every field of every row, and nested serializers, method fields and hyperlinks multiply that. Paginate, use a slim read-only list serializer, and never build a serializer per row.

open as a page