Skip to content

Serializers

This module provides enhanced serializer utilities for Django REST Framework.

OrderedFieldsMixin

Ensures predictable field ordering in API responses.

FIELD_ORDER = ("id", "name", "created_at")

Behavior

If FIELD_ORDER is defined:

  • Fields listed in FIELD_ORDER appear first
  • Remaining fields follow original serializer order

RequestActorViewMixin

Adds convenience properties for accessing the requesting user and their profile.

actor

A cached property returning the authenticated request.user, or None if there is no request, no user, or the user isn't authenticated.

def perform_create(self, serializer):
    serializer.save(owner=self.actor)

Note

This differs from the plain self.request.user lookup previously described under CommonMixin: an anonymous request now resolves to None rather than Django's AnonymousUser instance. Code that branches on self.actor truthiness is unaffected, but code that expects an AnonymousUser object specifically should be updated.

actor_profile

A cached property returning actor.related_profile, or None if there is no actor (unauthenticated) or the attribute doesn't exist.

def get_queryset(self):
    if self.actor_profile:
        return Order.objects.filter(profile=self.actor_profile)
    return Order.objects.none()

Tip

Both properties are @cached_property, so they're computed once per request/view instance — safe to access repeatedly across perform_* and get_* hooks without re-hitting related_profile.

RoleBaseReadOnlyFieldsMixin

Controls field editability based on user role.

NON_EDITABLE_FIELDS_BY_ROLE = {
    "user": {"is_admin"},
    "staff": set(),
}

NoUpdateFieldsMixin

Prevents specific fields from being updated after creation.

class Meta:
    no_update_fields = ["email"]

Behavior

Action Behavior
create fields are writable
update fields become read-only
partial_update fields become read-only

Validation rule

no_update_fields must be:

  • list
  • or tuple

Otherwise a TypeError is raised.

How it works

  • Reads request.user.user_type
  • Matches against role configuration
  • Marks matching fields as read_only

ModelSerializer (Core Base)

The main serializer base class used in drf-corekit.

Features

  • Ordered field output
  • Role based read only fields
  • Immutable fields after creation

Combined Usage Example

from drf_corekit.serializers import ModelSerializer

class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"
        no_update_fields = ["email"]

Confirmation Serializers

Provides serializers for operations that require explicit user confirmation before execution.

Typical use cases include:

  • account suspension
  • account reactivation
  • account deactivation
  • account deletion
  • password reset triggers

ConfirmSerializer

Requires explicit confirmation before an action can proceed.

class ConfirmSerializer(serializers.Serializer):
    confirm = serializers.BooleanField()

Behavior

The request is considered valid only when:

{
  "confirm": true
}

Validation rule

If confirm is:

  • omitted
  • false

a validation error is raised.

Example

{
  "confirm": true
}

ConfirmReasonSerializer

Extends ConfirmSerializer by requiring a reason for the action.

class ConfirmReasonSerializer(ConfirmSerializer):
    reason = serializers.CharField(max_length=255)

Behavior

The request is considered valid only when:

  • confirm is true
  • reason is provided
  • reason is not blank

Example

{
  "confirm": true,
  "reason": "Violation of platform policies"
}

ModelSerializer

The default serializer base class for the project, composing the four mixins above onto DRF's ModelSerializer so individual serializers don't have to opt into each one by hand.

class ModelSerializer(
    OrderedFieldsMixin,
    RoleBaseReadOnlyFieldsMixin,
    RequestActorSerializerMixin,
    NoUpdateFieldsMixin,
    serializers.ModelSerializer,
):
    """
    Core DRF serializer base used across drf-corekit.

    Provides:

    - Deterministic field ordering (`OrderedFieldsMixin`)
    - Role-based read-only fields (`RoleBaseReadOnlyFieldsMixin`)
    - `actor` / `actor_profile` properties (`RequestActorSerializerMixin`)
    - Update-protection fields via `no_update_fields` (`NoUpdateFieldsMixin`)
    """
Mixin Adds
OrderedFieldsMixin FIELD_ORDER support
RoleBaseReadOnlyFieldsMixin NON_EDITABLE_FIELDS_BY_ROLE / DEFAULT_READONLY_FOR_UNKNOWN_ROLE
RequestActorSerializerMixin actor / actor_profile properties
NoUpdateFieldsMixin Meta.no_update_fields support
class EmployeeSerializer(ModelSerializer):
    NON_EDITABLE_FIELDS_BY_ROLE = {UserType.USER: {"is_admin", "salary"}}
    FIELD_ORDER = ("id", "name")

    class Meta:
        model = Employee
        fields = ["id", "name", "is_admin", "salary"]
        no_update_fields = ["name"]

Note

None of the four mixins require configuration to be safe defaults: with no FIELD_ORDER, no NON_EDITABLE_FIELDS_BY_ROLE, and no Meta.no_update_fields, each one is a no-op. A serializer can subclass ModelSerializer and opt into only the pieces it needs.

Note

The mixin order among OrderedFieldsMixin, RoleBaseReadOnlyFieldsMixin, RequestActorSerializerMixin, and NoUpdateFieldsMixin isn't significant here — none of them override the same method as another, so there's no super() chain whose order matters, and self.actor resolves correctly via the MRO regardless of where RequestActorSerializerMixin sits among the bases. (This corrects the general ordering tip given earlier for RoleBaseReadOnlyFieldsMixin + RequestActorSerializerMixin on their own — it only applies when two mixins in the chain override the same method and rely on super().)