drf-nested-routers icon indicating copy to clipboard operation
drf-nested-routers copied to clipboard

'parent_pk' KeyError when posting/putting to a nested url

Open cerahmed opened this issue 1 year ago • 4 comments

I have the following two simplified models:

# devices/models.py
class Relay(Device):
    input_pin = models.PositiveIntegerField()
# logs/models.py
class RelayLog(BaseLog):
    relay = models.ForeignKey(Relay, related_name='logs', on_delete=models.CASCADE)

With serializers:

# devices/serializers.py
class RelaySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Relay
        fields = ['url', 'input_pin']

# logs/serializers.py
class RelayLogSerializer(NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'relay_pk': 'relay__pk'
    }
    class Meta:
        model = RelayLog
        fields = ['url', 'relay']

With viewsets:

# devices/views.py
class RelayViewSet(viewsets.ModelViewSet):
    serializer_class = RelaySerializer
    queryset = Relay.objects.all().order_by('id')

# logs/views.py
class RelayLogViewSet(viewsets.ModelViewSet):
    serializer_class = RelayLogSerializer
    queryset = RelayLog.objects.all()

    def get_queryset(self):
        return RelayLog.objects.filter(relay=self.kwargs.get('relay_pk')).order_by('-id')

and finally urls:

# devices/urls.py
from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r'relays', views.RelayViewSet)

# logs/urls.py
from rest_framework_nested import routers
from . import views

router = routers.NestedDefaultRouter(relay_router, r'relays', lookup='relay')
router.register(r'logs', api_views.RelayLogViewSet)

Everything works fine, I can GET http://localhost/relays/8/logs/ and http://localhost/relays/8/logs/16 to list and show detail for the specific relay logs, respectively.

However, when looking at http://localhost/relays/8/logs/ and try to post a new relay log, or when looking at http://localhost/relays/8/logs/14 and try to PUT to change some fields on it, I get a KeyError at /relays/8/logs/ 'parent_pk'.

After digging in the source code for a reason why there is parent_pk, it seems that it is somewhy forced into relations.py - line 24. Trying to remove the key parent_pk and its corresponding value seems to fix the issue.

I'm not sure if I have misconfigured something or if the source code has a bug?

cerahmed avatar Aug 16 '23 22:08 cerahmed

I have the same issue, once you get past the first level of nesting POST and PUT return the parent_pk key error. Have you found a workaround @cerahmed

JayCeeJr avatar Nov 19 '23 15:11 JayCeeJr

@JayCeeJr Unfortunately I did not. However I moved to using drf-nested-resources as a working alternative, which solved my issue. Make sure to read my closed issue in that repo tho, you may run in the same issue that I encountered there.

cerahmed avatar Nov 19 '23 15:11 cerahmed

@JayCeeJr Unfortunately I did not. However I moved to using drf-nested-resources as a working alternative, which solved my issue. Make sure to read my closed issue in that repo tho, you may run in the same issue that I encountered there.

it's not maintained for 5 years now :/

patroqueeet avatar Mar 08 '24 12:03 patroqueeet

it's not maintained for 5 years now :/

Yeah that's unfortunate; good thing is it still works for me. I've seen some updates to this repo, wondering if anyone tried this recently and it got fixed?

cerahmed avatar May 15 '24 17:05 cerahmed