diff --git a/rest_framework/fields.py b/rest_framework/fields.py index fdfba13f26..de911df7eb 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -125,9 +125,14 @@ def set_value(dictionary, keys, value): for key in keys[:-1]: if key not in dictionary: dictionary[key] = {} + elif type(dictionary[key]) is not dict: + dictionary[key] = {'': dictionary[key]} dictionary = dictionary[key] - dictionary[keys[-1]] = value + if keys[-1] in dictionary and type(dictionary[keys[-1]]) is dict: + dictionary[keys[-1]][''] = value + else: + dictionary[keys[-1]] = value def to_choices_dict(choices): diff --git a/tests/test_fields.py b/tests/test_fields.py index fdd570d8a6..cdedf76142 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -14,7 +14,7 @@ import rest_framework from rest_framework import exceptions, serializers from rest_framework.fields import ( - BuiltinSignatureError, DjangoImageField, is_simple_callable + BuiltinSignatureError, DjangoImageField, is_simple_callable, set_value ) # Tests for helper functions. @@ -2380,3 +2380,65 @@ def validate(self, obj): ), ] } + + +# Tests for set_value function +# ---------------------------- + +class TestSetValue: + + def test_no_keys(self): + """ + If no keys are provided, but a dict as value, add the dicts + """ + d = {'a': 1} + set_value(d, [], {'b': 2}) + assert d == {'a': 1, 'b': 2} + + def test_one_key(self): + """ + If a key + value provided, add the value to the dict with key + """ + d = {'a': 1} + set_value(d, ['x'], 2) + assert d == {'a': 1, 'x': 2} + + def test_many_keys(self): + """ + With many keys, add the item to the in-most dict + """ + d = {'a': 1} + set_value(d, ['x', 'y'], 2) + assert d == {'a': 1, 'x': {'y': 2}} + + def test_many_keys_existing(self): + """ + With many keys with existing in-built dict + """ + d = {'a': 1, 'x': {'a': 2}} + set_value(d, ['x', 'y'], 3) + assert d == {'a': 1, 'x': {'a': 2, 'y': 3}} + + def test_conflicting_keys(self): + """ + If a value exists where a key will be added, use a blank key for old value + """ + d = {'a': 1, 'x': 2} + set_value(d, ['x', 'y'], 3) + assert d == {'a': 1, 'x': {'': 2, 'y': 3}} + + def test_reverse_conflict(self): + """ + If a dict exists and a value is to be added, add it as blank key + """ + d = {'a': 1, 'x': {'y': 2}} + set_value(d, ['x'], 3) + assert d == {'a': 1, 'x': {'y': 2, '': 3}} + + def test_overwrite_conflict(self): + """ + If a newer final value comes, replace with the older + """ + d = {'a': 1, 'x': 2} + set_value(d, ['x'], 3) + assert d == {'a': 1, 'x': 3} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy