alanjds / drf-nested-routers

Nested Routers for Django Rest Framework
https://pypi.org/project/drf-nested-routers/
Apache License 2.0
1.66k stars 157 forks source link

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

Open cerahmed opened 1 year ago

cerahmed commented 1 year ago

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?

JayCeeJr commented 9 months ago

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

cerahmed commented 9 months ago

@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.

patroqueeet commented 6 months ago

@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 :/

cerahmed commented 4 months ago

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?