Skip to content

get_related_resource_type failing for polymorphic serializers #621

Closed
@favll

Description

@favll

We have run into a problem where DRF JSON API resolves the wrong related resource type when trying to include a resource using a polymorphic serializer. Specifically, DRF JSON API will resolve the base model instead of the inherited model.

Below is an abbreviated example for the issue we are running into. In the following example utils.get_related_resource_type will resolve the parent_model to models.Product instead of models.ArtProduct (line here). Subsequently, the method will try to access art_details on the parent_model which will fail since it only exists on models.ArtProduct and not models.Product (line here).

A proposed fix would be to resolve the parent_model by checking if the parent_serializer is a polymorphic serializer and resolving the parent_model with something along the lines of:
parent_serializer.get_polymorphic_serializer_for_instance(parent_serializer.instance).Meta.model

If desired, I can provide further clarification and prepare a PR.

class ArtProductSerializer(serializers.ModelSerializer):
    price = MoneyField(max_digits=19, decimal_places=4)

    included_serializers = {
        "art_details": ArtDetailSerializer,
    }

    class JSONAPIMeta:
        included_resources = ("art_details",)
        resource_name = "ArtProduct"

    class Meta:
        fields = (
            "id",
            "price",
            "art_details",
        )
        model = models.ArtProduct


class PolymorphicProductSerializer(serializers.PolymorphicModelSerializer):
    polymorphic_serializers = [ArtProductSerializer]

    class Meta:
        model = models.Product


class CartItemSerializer(serializers.ModelSerializer):

    included_serializers = {
        "product": PolymorphicProductSerializer,
    }

    class Meta:
        model = models.CartItem
        fields = ("id", "product")


class CartSerializer(serializers.ModelSerializer):
    included_serializers = {
        "items": CartItemSerializer,
    }

    class Meta:
        model = models.Cart
        fields = ("id", "items")
        read_only_fields = ("id", "items")

    class JSONAPIMeta:
        included_resources = ("items", "items.product")

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions