pynetbox
pynetbox copied to clipboard
Fix cable serialize
Fixes: #555
The way pynetbox currently handles mixed lists doesn't allow to re-instantiate the proper nested object types when loading values from a serialized() object. This is because the generic_list_parser "gobbles" that information by construction specific Record types from the mixed list.
Example:
>>> print(cable.serialize())
{'a_terminations': [530082],
'b_terminations': [314260],
'color': '',
'comments': '',
'created': '2022-05-03T02:00:00+02:00',
'custom_fields': {},
'description': '',
'display': '1001',
'id': 155652,
'label': '1001',
'last_updated': '2022-06-29T14:36:49.386886+02:00',
'length': None,
'length_unit': None,
'status': 'connected',
'tags': [],
'tenant': 2510,
'type': '',
'url': 'https://localhost:8000/api/dcim/cables/155652/'}
Patching the record a_terminations / b_terminations with new ID wouldn't work as with other nested Record types as in this case the API expects a dict with object_type and object_id keys.
I propose to solve this by introducing a GenericListItem class that more accurately stores the state of the API response, while allowing a nicer serialization
>>> print(cable.serialize())
{'a_terminations': [{'object_id': 530082, 'object_type': 'dcim.interface'}],
'b_terminations': [{'object_id': 314260, 'object_type': 'dcim.frontport'}],
'color': '',
'comments': '',
'created': '2022-05-03T02:00:00+02:00',
'custom_fields': {},
'description': '',
'display': '1001',
'id': 155652,
'label': '1001',
'last_updated': '2022-06-29T14:36:49.386886+02:00',
'length': None,
'length_unit': None,
'status': 'connected',
'tags': [],
'tenant': 2510,
'type': '',
'url': 'https://localhost:8000/api/dcim/cables/155652/'}
The __getattr__ on the new class, allows to maintain backward compatibility to some extent.
>>> print(cables.a_terminations[0].label)
'ETH-1'
This involves a change in type of objects returned in mixed/generic lists now always being GenericListItem