Skip to content

Commit

Permalink
fixes bug with custom fields in _identifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
Kircheneer committed Dec 4, 2023
1 parent fd724ed commit abec51b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
21 changes: 19 additions & 2 deletions nautobot_ssot/contrib.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,25 @@ def _check_field(cls, name):
raise ValueError(f"Field {name} is not defined on the model.")

def get_from_db(self):
"""Get the ORM object for this diffsync object from the database using the identifiers."""
return self._model.objects.get(**self.get_identifiers())
"""Get the ORM object for this diffsync object from the database using the identifiers.
TODO: Currently this does not support many to many relationships.
"""
parameters = {}
custom_field_lookup = {}
type_hints = get_type_hints(self, include_extras=True)
is_custom_field = False
for key, value in self.get_identifiers().items():
metadata_for_this_field = getattr(type_hints[key], "__metadata__", [])
for metadata in metadata_for_this_field:
if isinstance(metadata, CustomFieldAnnotation):
custom_field_lookup[metadata.name] = value
is_custom_field = True
if not is_custom_field:
parameters[key] = value
if custom_field_lookup:
parameters["_custom_field_data__contains"] = custom_field_lookup
return self._model.objects.get(**parameters)

def update(self, attrs):
"""Update the ORM object corresponding to this diffsync object."""
Expand Down
33 changes: 28 additions & 5 deletions nautobot_ssot/tests/test_contrib.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,34 @@ def test_basic_deletion(self):
class BaseModelCustomFieldTest(TestCase):
"""Test for manipulating custom field content through the shared case model code."""

@classmethod
def setUpTestData(cls):
cls.custom_field_name = "Is Global"
cls.custom_field = CustomField.objects.create(
key=cls.custom_field_name, label=cls.custom_field_name, type="boolean"
)
cls.custom_field.content_types.set([ContentType.objects.get_for_model(Provider)])

def test_custom_field_get(self):
"""Test whether loading a model with a custom field set as the identifier works."""

class ProviderModel(NautobotModel):
"""Test model for testing custom field functionality."""

_model = Provider
_identifiers = (
"name",
"is_global",
)

name: str
is_global: Annotated[bool, CustomFieldAnnotation(name="Is Global")] = False

provider = Provider.objects.create(name="Test", _custom_field_data={"Is Global": True})
self.assertEqual(provider, ProviderModel(name="Test", is_global=True).get_from_db())

def test_custom_field_set(self):
"""Test whether setting a custom field value works."""
custom_field_name = "Is Global"
custom_field = CustomField.objects.create(key=custom_field_name, label=custom_field_name, type="boolean")
custom_field.content_types.set([ContentType.objects.get_for_model(Provider)])

class ProviderModel(NautobotModel):
"""Test model for testing custom field functionality."""
Expand All @@ -402,7 +425,7 @@ class ProviderModel(NautobotModel):

name: str

is_global: Annotated[bool, CustomFieldAnnotation(name=custom_field_name)] = False
is_global: Annotated[bool, CustomFieldAnnotation(name="Is Global")] = False

provider_name = "Test Provider"
provider = Provider.objects.create(name=provider_name)
Expand All @@ -413,7 +436,7 @@ class ProviderModel(NautobotModel):

provider.refresh_from_db()
self.assertEqual(
provider.cf[custom_field_name],
provider.cf[self.custom_field_name],
updated_custom_field_value,
"Setting a custom field through 'NautobotModel' does not work.",
)
Expand Down

0 comments on commit abec51b

Please sign in to comment.