django-rest-framework-json-api icon indicating copy to clipboard operation
django-rest-framework-json-api copied to clipboard

inflection is not performed by AutoPrefetchMixin for included resources

Open masda70 opened this issue 5 years ago • 1 comments

On v4.0.0, inflection is not performed by the AutoPrefetchMixin for included resources, contrary to the JSONRenderer.

Suppose the following data model, serializers and viewsets:

from django.db import models
from rest_framework import viewsets, mixins
from rest_framework_json_api import views, serializers

class Album(models.Model):
    title = models.TextField()

class Track(models.Model)
    title = models.TextField()
    is_part_of = models.ManyToManyField(Album)

class AlbumSerializer(serializers.ModelSerializer):
    class Meta:
        model = Album
        fields = ["title"]

class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Track
        fields = ["title", "is_part_of"]

    included_serializers = {
        "is_part_of": AlbumSerializer,
    }
class Track(
    views.AutoPrefetchMixin,
    views.RelatedMixin,
    mixins.ListModelMixin,
    viewsets.GenericViewSet
):
    serializer_class = serializers.TrackSerializer
    queryset = Track.objects.all()

Both GET /tracks?include=is-part-of and GET /tracks?include=isPartOf correctly return the set all of tracks along with their albums' titles embedded within the included section of the response.

However, prefetch of the tracks' related album objects is not performed, as one would expect from views.AutoPrefetchMixin.

My workaround is to perform GET tracks?include=is_part_of, which returns the same thing as the above two queries but also performs prefetching.

My investigation has shown me that the AutoPrefetchMixin does not perform inflection of the result of get_included_resources that it uses to create the argument passed to prefetch_related. The JSONRenderer does the following instead:

        included_resources = copy.copy(included_resources)
        included_resources = [inflection.underscore(value) for value in included_resources]

masda70 avatar Dec 12 '20 14:12 masda70

Thanks for reporting this. When having a quick glance at the code it seems that this is indeed an issue.

Marking this as a bug. PR is very welcome.

For some who wants to have a look at this, here is the best spot to start.

sliverc avatar Dec 12 '20 18:12 sliverc