3

I am trying to generate nested HATEOAS links in a serializer using the drf-nested-routes package. My current setup would be as follows:

/resource_a/<pk>
/resource_a/<pk>/resource_b/<pk>
/resource_a/<pk>/resource_b/<pk>
/resource_a/<pk>/resource_b/<pk>/resource_c

I am unable to create a HyperlinkedIdentityField that points to the last route. According to the documentation, one can create hyperlinked fields like this:

nameservers = HyperlinkedIdentityField(
    view_name='domain-nameservers-list',
    lookup_url_kwarg='domain_pk'
)

Or

nameservers = NestedHyperlinkedRelatedField(
    many=True,
    read_only=True,   # Or add a queryset
    view_name='domain-nameservers-detail'
    parent_lookup_url_kwargs={'domain_pk': 'domain__pk'}
)

But these approaches fail when trying to reach a resource that is 2 layers deep in the URL hierarchy. The first method is not compatible, as it does not allow to add a second lookup_url_kwarg, and as for the second one, it throws an exception (ImproperlyConfigured) when configuring with the (in my opinion) proper attributes (resource_a__pk, resource_b__pk).

Is this at all possible with this package? Otherwise I will resort to a simpler solution using a SerializerMethodField:

resource_c = serializers.SerializerMethodField()

def get_resource_c(self, obj):
        url = reverse('resource_b-resource_c-list', kwargs=dict(resource_a_pk=obj.resource_a.pk, resource_b_pk=obj.pk))
        return self.context['request'].build_absolute_uri(url)

Thanks in advance!

Axel
  • 3,331
  • 11
  • 35
  • 58
martinarroyo
  • 9,389
  • 3
  • 38
  • 75
  • From my experience there are problems when you register your url's like that `/resource_a//resource_b//resource_c` and you want to use it in a `reverse` call. Did you duplicate the `` tag in your url's? – Johannes Reichard Sep 29 '17 at 10:49
  • I did not register the URLs like that, that was the resulting API scheme. I basically followed the example in the [docs](https://github.com/alanjds/drf-nested-routers/#quickstart) – martinarroyo Sep 29 '17 at 11:01
  • Can you add an real live example, because checking out the sourcecode for a `NestedHyperlinkedRelatedField` you can see that it's doing some string splitting etc https://github.com/alanjds/drf-nested-routers/blob/c60e752b797d3acbec72ab1b90ab35772496cebd/rest_framework_nested/relations.py#L20. So when this happens it's easier to debug a real live example. – Johannes Reichard Sep 29 '17 at 11:26
  • @martinarroyo I've done this before using `NestedHyperlinkedRelatedField ` and it definitely works. My guess is that your configuration is not correct. One thing I noticed is that you use `parent_lookup_url_kwargs` while in my case I use `parent_lookup_kwargs`. Based on your explanation I think it needs to look like this `NestedHyperlinkedRelatedField(..., parent_lookup_kwargs={'resource_a_pk': ''})`. – Vignesh Oct 02 '17 at 16:18
  • 1
    Thanks @vignesh That did it. The docs mention the `parent_lookup_url_kwargs` parameter instead though. I just passed these parameters: `view_name='resource-c-list', parent_lookup_kwargs={'resource_a_pk': 'a__pk'}, lookup_url_kwarg='b_pk'`. Feel free to add your comment as an answer so that I can mark the question as closed. – martinarroyo Oct 04 '17 at 08:34
  • Glad to be of help! – Vignesh Oct 05 '17 at 03:36

1 Answers1

3

I've done this before using NestedHyperlinkedRelatedField and it definitely works. My guess is that your configuration is not correct. One thing I noticed is that you use parent_lookup_url_kwargs while in my case I use parent_lookup_kwargs.

Based on your explanation I think it needs to look like this

NestedHyperlinkedRelatedField(..., 
    parent_lookup_kwargs={
          'resource_a_pk': '<how to reach resource_a pk from resource_b>'})
Vignesh
  • 504
  • 5
  • 13