Django REST Framework Generic Relations

raw JSON →
2.2.0 verified Fri May 01 auth: no python

A Django REST Framework extension providing a GenericRelatedField for serializers to handle generic foreign keys (GFKs). Version 2.2.0 supports Python >=3.8 and DRF >=3.12. Stable, infrequent releases.

pip install rest-framework-generic-relations
error AttributeError: module 'rest_framework_generic_relations' has no attribute 'GenericRelatedField'
cause Importing from the top-level module instead of the fields submodule.
fix
Use 'from rest_framework_generic_relations.fields import GenericRelatedField'
error TypeError: 'NoneType' object is not callable
cause serializer_polymorphic or serializer_class not set, or serializer_polymorphic returns None.
fix
Provide a valid serializer_polymorphic dict mapping models to serializers.
gotcha GenericRelatedField requires a serializer_polymorphic mapping or custom serializer_class; omitting either will raise an AttributeError.
fix Provide a dictionary mapping ContentType model classes to serializers via serializer_polymorphic.
gotcha The field expects the GFK to be properly set up on the model with a GenericForeignKey; otherwise it will fail to resolve.
fix Ensure the model has a GenericForeignKey field pointing to the content type and object id fields.
deprecated In version 2.x, the serializer_class parameter is deprecated in favor of serializer_polymorphic.
fix Use serializer_polymorphic instead to specify serializers per model.

Define a serializer with a GenericRelatedField that provides different serializers based on the GFK content type.

from rest_framework_generic_relations.fields import GenericRelatedField
from rest_framework import serializers
from myapp.models import Tag, Product, Article

class TaggedItemSerializer(serializers.ModelSerializer):
    content_object = GenericRelatedField(
        serializer_polymorphic=lambda: {
            Product: ProductSerializer,
            Article: ArticleSerializer,
        }
    )
    class Meta:
        model = Tag
        fields = ['id', 'tag', 'content_object']