diff --git a/example/tests/integration/test_sparse_fieldsets.py b/example/tests/integration/test_sparse_fieldsets.py new file mode 100644 index 00000000..d0d17128 --- /dev/null +++ b/example/tests/integration/test_sparse_fieldsets.py @@ -0,0 +1,13 @@ +from django.core.urlresolvers import reverse + +import pytest + + +pytestmark = pytest.mark.django_db + + +def test_sparse_fieldset_ordered_dict_error(multiple_entries, client): + base_url = reverse('entry-list') + querystring = '?fields[entries]=blog,headline' + response = client.get(base_url + querystring) # RuntimeError: OrderedDict mutated during iteration + assert response.status_code == 200 # succeed if we didn't fail due to the above RuntimeError diff --git a/rest_framework_json_api/serializers.py b/rest_framework_json_api/serializers.py index e0ea7657..8fd78292 100644 --- a/rest_framework_json_api/serializers.py +++ b/rest_framework_json_api/serializers.py @@ -53,7 +53,9 @@ def __init__(self, *args, **kwargs): pass else: fieldset = request.query_params.get(param_name).split(',') - for field_name, field in self.fields.items(): + # iterate over a *copy* of self.fields' underlying OrderedDict, because we may modify the + # original during the iteration. self.fields is a `rest_framework.utils.serializer_helpers.BindingDict` + for field_name, field in self.fields.fields.copy().items(): if field_name == api_settings.URL_FIELD_NAME: # leave self link there continue if field_name not in fieldset: