| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- from urllib.parse import urlencode
- from django.http import QueryDict
- from django.utils.datastructures import MultiValueDict
- from netbox.models.features import CloningMixin
- __all__ = (
- 'dict_to_querydict',
- 'normalize_querydict',
- 'prepare_cloned_fields',
- )
- def dict_to_querydict(d, mutable=True):
- """
- Create a QueryDict instance from a regular Python dictionary.
- """
- qd = QueryDict(mutable=True)
- for k, v in d.items():
- item = MultiValueDict({k: v}) if isinstance(v, (list, tuple, set)) else {k: v}
- qd.update(item)
- if not mutable:
- qd._mutable = False
- return qd
- def normalize_querydict(querydict):
- """
- Convert a QueryDict to a normal, mutable dictionary, preserving list values. For example,
- QueryDict('foo=1&bar=2&bar=3&baz=')
- becomes:
- {'foo': '1', 'bar': ['2', '3'], 'baz': ''}
- This function is necessary because QueryDict does not provide any built-in mechanism which preserves multiple
- values.
- """
- return {
- k: v if len(v) > 1 else v[0] for k, v in querydict.lists()
- }
- def prepare_cloned_fields(instance):
- """
- Generate a QueryDict comprising attributes from an object's clone() method.
- """
- # Generate the clone attributes from the instance
- if not issubclass(type(instance), CloningMixin):
- return QueryDict(mutable=True)
- attrs = instance.clone()
- # Prepare QueryDict parameters
- params = []
- for key, value in attrs.items():
- if type(value) in (list, tuple):
- params.extend([(key, v) for v in value])
- elif value is not False and value is not None:
- params.append((key, value))
- else:
- params.append((key, ''))
- # Return a QueryDict with the parameters
- return QueryDict(urlencode(params), mutable=True)
|