Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions rest_framework_nested/viewsets.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

import contextlib
from typing import Any, Generic, Iterator, TypeVar
from typing import Any, Dict, Generic, Iterator, List, TypeVar, Union, cast

from django.core.exceptions import ImproperlyConfigured
from django.db.models import Model, QuerySet
Expand All @@ -10,10 +10,13 @@
from rest_framework.serializers import BaseSerializer

T_Model = TypeVar('T_Model', bound=Model)
RequestData = Union[Dict[str, Any], List[Dict[str, Any]]]


@contextlib.contextmanager
def _force_mutable(querydict: QueryDict | dict[str, Any]) -> Iterator[QueryDict | dict[str, Any]]:
def _force_mutable(
querydict: QueryDict | dict[str, Any] | list[dict[str, Any]],
) -> Iterator[QueryDict | dict[str, Any] | list[dict[str, Any]]]:
"""
Takes a HttpRequest querydict from Django and forces it to be mutable.
Reverts the initial state back on exit, if any.
Expand Down Expand Up @@ -74,13 +77,14 @@ def initial(self, request: Request, *args: Any, **kwargs: Any) -> None:
if getattr(self, 'swagger_fake_view', False):
return

request_data = cast(RequestData, request.data)
for url_kwarg, fk_filter in self._get_parent_lookup_kwargs().items():
# fk_filter is alike 'grandparent__parent__pk'
parent_arg = fk_filter.partition('__')[0]
for querydict in [request.data, request.query_params]:
for querydict in [request_data, request.query_params]:
with _force_mutable(querydict):
if isinstance(querydict, list):
for querydict_item in querydict:
querydict_item[parent_arg] = kwargs[url_kwarg]
else:
querydict[parent_arg] = kwargs[url_kwarg]
querydict[parent_arg] = kwargs[url_kwarg]