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

Reverse the relationship names in includes

Open schtibe opened this issue 9 years ago • 6 comments

I am not a 100% sure about this, but when all resource names are dasherized and pluralized, shouldn't the included names be plural and dasherized too?

By included names I mean: http://jsonapi.org/format/#fetching-includes

Right now, I retrieve data like this: /api/v1/vehicle-checks?include=calendar_block, which shows the mix in naming style: the ressource is dasherized and pluralized, the included ressource is not.

This request works, and ``?include=calendar-blocks` does not, which is obvious when looking at serializers.py lines 75 - 80.

So my question is, shouldn't some reversing occur to match the naming style, similar to how the output is changed?

schtibe avatar Feb 08 '16 17:02 schtibe

I feel like that would be reasonable. Perhaps using the JSON_API_FORMAT_RELATION_KEYS setting to reverse it to snake_case?

jerel avatar Feb 08 '16 20:02 jerel

I suspect that it has to have an option to tell how to reverse the names... in case someone isn't following the pep8 standards.

Something like JSON_API_PARSE_RELATION_KEYS

schtibe avatar Feb 09 '16 14:02 schtibe

Another way to solve this would be to use different names in the included_serializers.. although I am not quite sure if the names there have to match the field names!?

schtibe avatar Feb 11 '16 11:02 schtibe

I think parsing it like you're doing in the PR is the right direction. The serializer doesn't strike me as the right way to stick this but I'm open to a counter argument

jerel avatar Feb 11 '16 16:02 jerel

@schtibe @jerel I just found myself in your same situation :). However I have a question: should includes refer always to the resource_name of the resource you want to include? or should they refer to the field name you defined in the serializer?

Let me explain with some dummy (incomplete) code:

class Car(object):
   pass

class Passenger(object):
  passenger = ForeignKey(Car, related_name='human-passengers')


class PassengerSerializer(serializer.ModelSerializer):
   class Meta:
       model = Passenger

class CarSerializer(serializer.ModelSerializer):
   passengers = ResourceRelatedField(many=True, source='human-passengers', read_only=True)

   include_serializers = dict(passengers=PassengerSerializer)
   class Meta:
       model = Car

class Passenger(viewsets.ReadOnlyModelViewSet):
   resource_name = 'human-passengers'
   serializer_class = PassengerSerializer

class Car(viewsets.ReadOnlyModelViewSet):
   serializer_class = CarSerializer

Now If I did GET /cars/1/?include=human-passengers I'd expect the view to return the human-passengers resource included in the response (but it won't).

At the moment, to get this I'd have to do GET /cars/1/?include=passengers, because passengers matches the field name in CarSerializer.

Acording to: http://jsonapi.org/format/#document-resource-objects http://jsonapi.org/format/#fetching-includes

What you put in the includes should be the whatever the type key says. In this case, the type key for the Passenger resource should be human-passengers (because DRF jsonapi allows you to explicitely set resource_name).

jesushernandez avatar Feb 16 '16 17:02 jesushernandez

This is a fairly old issue and there might be some confusion. So to clarify the specification states that the include query param are relationship field names and not resource names (see https://jsonapi.org/format/#fetching-includes).

So simply running the include name through the utils.undo_format_field_name will do it. There is already some underscoring of include names happening here but it does not take into consideration that includes maybe nested (e.g. include=author-bio.author-type)

This issue is related to #871 Maybe fixing both issue in one PR might be considered if the unformatting could happen in the utility method utils.get_included_resources).

sliverc avatar Oct 11 '21 16:10 sliverc