Serializers Reference
Serializers handle conversion between Django model instances and JSON-LD representations for ActivityPub federation. They use field-based configuration to control how data is embedded or referenced.
Core Serializer Classes
ContextModelSerializer
activitypub.serializers.linked_data.ContextModelSerializer
Bases: Serializer
Generic serializer that converts any context model to expanded JSON-LD.
Automatically uses LINKED_DATA_FIELDS from the context model.
Handles access control via optional show_
to_representation(instance)
Convert context model instance to expanded JSON-LD.
Supports explicit field overrides - fields defined in the serializer class will be used instead of automatic introspection for those fields.
Returns dict with full predicate URIs as keys.
Serializes individual context model instances to expanded JSON-LD.
Uses the model's LINKED_DATA_FIELDS mapping to convert Django fields
to RDF predicates.
Access Control:
Serializers support optional show_<field_name>() methods for
field-level access control:
class ActorContextSerializer(ContextModelSerializer):
def show_followers(self, instance, viewer):
# Only show followers to the actor themselves
return viewer and viewer.uri == instance.reference.uri
LinkedDataSerializer
activitypub.serializers.linked_data.LinkedDataSerializer
Bases: BaseSerializer
Serializer for linked data models. Given a reference, find all the associated context models that have data and produces the merged JSON-LD.
Supports embedded mode for simplified representation when referenced from other documents.
__init__(instance, embedded=False, **kwargs)
Initialize the serializer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instance
|
Reference object to serialize |
required | |
embedded
|
If True, uses simplified embedded serializers |
False
|
|
**kwargs
|
Additional arguments passed to parent |
{}
|
get_compact_context(instance)
Build the @context array for JSON-LD compaction.
Collects context URLs and EXTRA_CONTEXT from context models that have data. Orders contexts as: AS2 first, other contexts, then extensions dict.
Returns:
| Type | Description |
|---|---|
|
List representing the @context array |
Main serializer that coordinates multiple context models for a reference. Automatically discovers which context models have data and merges their output.
Usage:
from activitypub.serializers import LinkedDataSerializer
serializer = LinkedDataSerializer(
instance=reference,
context={'viewer': viewer, 'request': request}
)
expanded_data = serializer.data
Embedded vs Referenced Serialization:
The serializer can use different serializers for main subjects vs embedded objects:
serializer = LinkedDataSerializer(
instance=reference,
context={'viewer': viewer},
embedded=False # Main subject - shows all fields
)
# For embedded objects, automatically uses embedded variant if configured
embedded_serializer = LinkedDataSerializer(
instance=reference,
context={'viewer': viewer},
embedded=True # Embedded - omits collection endpoints
)
Collection Serializers
CollectionContextSerializer
activitypub.serializers.as2.CollectionContextSerializer
Bases: ContextModelSerializer
Collection serializer that embeds the first page.
When viewing a collection, the first page is embedded so clients can immediately see some items without an additional request.
Specialized serializer for collection contexts. Handles pagination and item serialization.
NodeInfo Serializer
activitypub.serializers.nodeinfo.NodeInfoSerializer
Bases: Serializer
Serializes server metadata for the NodeInfo protocol.
Custom Serialization
The toolkit supports custom serializers for specific context models:
FEDERATION = {
'CUSTOM_SERIALIZERS': {
ObjectContext: CustomObjectSerializer,
}
}
Custom serializers must inherit from ContextModelSerializer and
implement the same interface:
from activitypub.serializers import ContextModelSerializer
class CustomObjectSerializer(ContextModelSerializer):
def to_representation(self, instance):
data = super().to_representation(instance)
# Add custom fields or transformations
return data
def show_sensitive_field(self, instance, viewer):
# Custom access control
return viewer and self.can_view(viewer, instance)
Serialization Pipeline
The complete serialization pipeline involves two stages:
- Serialization -
LinkedDataSerializerproduces expanded JSON-LD with full predicate URIs. Field definitions control whether related objects are embedded, referenced, or omitted. - Compaction - JSON-LD compaction produces readable output with
short keys and
@context
# In a view
serializer = LinkedDataSerializer(instance=reference, context={'viewer': viewer})
expanded = serializer.data
# Get compact context and compact the document
context = serializer.get_compact_context(reference)
compacted = jsonld.compact(expanded, context)
This separation of concerns allows each stage to focus on its responsibility: - Serializers extract and convert data, using field types to control structure - Compaction provides readability
Access Control Patterns
Field-Level Control
def show_inbox(self, instance, viewer):
# Only show inbox URL to owner
return viewer and viewer.uri == instance.reference.uri
Viewer-Aware Serialization
The viewer parameter in the context represents the authenticated
actor viewing the resource:
serializer = LinkedDataSerializer(
instance=actor_ref,
context={'viewer': requesting_actor_ref}
)
Serializers can use this to filter fields:
def show_followers(self, instance, viewer):
if not viewer:
return False # Anonymous viewers can't see followers
if viewer.uri == instance.reference.uri:
return True # Actor can see their own followers
return False # Others can't see followers
Field-Level Exclusion
Access control happens at serialization time, completely excluding fields from the document before they are even serialized.
Performance Considerations
Serialization involves:
- Querying context models for a reference
- Walking through LINKED_DATA_FIELDS mappings
- Resolving references for foreign keys
- Potentially recursing for embedded objects (via EmbeddedReferenceField)
For high-traffic endpoints, consider:
- Caching - Cache serialized output for public resources
- Selective Loading - Use
select_relatedandprefetch_relatedwhen querying references - Depth Limits -
EmbeddedReferenceFieldhas amax_depthparameter to prevent expensive recursion - Lazy Evaluation - Serializers evaluate lazily; access
.dataonly when needed