Coverage for utilities/querydict.py: 21%

27 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 18:35 +0000

1from urllib.parse import urlencode 

2 

3from django.http import QueryDict 

4from django.utils.datastructures import MultiValueDict 

5 

6from netbox.models.features import CloningMixin 

7 

8__all__ = ( 

9 'dict_to_querydict', 

10 'normalize_querydict', 

11 'prepare_cloned_fields', 

12) 

13 

14 

15def dict_to_querydict(d, mutable=True): 

16 """ 

17 Create a QueryDict instance from a regular Python dictionary. 

18 """ 

19 qd = QueryDict(mutable=True) 

20 for k, v in d.items(): 

21 item = MultiValueDict({k: v}) if isinstance(v, (list, tuple, set)) else {k: v} 

22 qd.update(item) 

23 if not mutable: 

24 qd._mutable = False 

25 return qd 

26 

27 

28def normalize_querydict(querydict): 

29 """ 

30 Convert a QueryDict to a normal, mutable dictionary, preserving list values. For example, 

31 

32 QueryDict('foo=1&bar=2&bar=3&baz=') 

33 

34 becomes: 

35 

36 {'foo': '1', 'bar': ['2', '3'], 'baz': ''} 

37 

38 This function is necessary because QueryDict does not provide any built-in mechanism which preserves multiple 

39 values. 

40 """ 

41 return { 

42 k: v if len(v) > 1 else v[0] for k, v in querydict.lists() 

43 } 

44 

45 

46def prepare_cloned_fields(instance): 

47 """ 

48 Generate a QueryDict comprising attributes from an object's clone() method. 

49 """ 

50 # Generate the clone attributes from the instance 

51 if not issubclass(type(instance), CloningMixin): 

52 return QueryDict(mutable=True) 

53 attrs = instance.clone() 

54 

55 # Prepare QueryDict parameters 

56 params = [] 

57 for key, value in attrs.items(): 

58 if type(value) in (list, tuple): 

59 params.extend([(key, v) for v in value]) 

60 elif value is not False and value is not None: 

61 params.append((key, value)) 

62 else: 

63 params.append((key, '')) 

64 

65 # Return a QueryDict with the parameters 

66 return QueryDict(urlencode(params), mutable=True)