As I said, I haven't tested it.
Looking at the code, I think it's an oversight. It says
termination_object = model.objects.get(device=device, name=name)
but circuit terminations don't have "device" or "name" attributes.
This code could be changed, but I can't see how you could identify a circuit termination without at least three pieces of data (provider, cid, side A/Z)
It may have been unintentional to allow circuit terminations as an option for the endpoints for CSV uploads in the first place.
If you have a large number of them to import, I suggest you write a small bit of python which talks to the Netbox API instead.
Regards,
Brian.
----------------------
class CableCSVForm(CustomFieldModelCSVForm):
# Termination A
side_a_device = CSVModelChoiceField(
queryset=Device.objects.all(),
to_field_name='name',
help_text='Side A device'
)
side_a_type = CSVContentTypeField(
queryset=ContentType.objects.all(),
limit_choices_to=CABLE_TERMINATION_MODELS,
help_text='Side A type'
)
side_a_name = forms.CharField(
help_text='Side A component name'
)
...
def clean_side_a_name(self):
return self._clean_side('a')
...
def _clean_side(self, side):
"""
Derive a Cable's A/B termination objects.
:param side: 'a' or 'b'
"""
assert side in 'ab', f"Invalid side designation: {side}"
device = self.cleaned_data.get(f'side_{side}_device')
content_type = self.cleaned_data.get(f'side_{side}_type')
name = self.cleaned_data.get(f'side_{side}_name')
if not device or not content_type or not name:
return None
model = content_type.model_class()
try:
termination_object = model.objects.get(device=device, name=name)
if termination_object.cable is not None:
raise forms.ValidationError(f"Side {side.upper()}: {device} {termination_object} is already connected")
except ObjectDoesNotExist:
raise forms.ValidationError(f"{side.upper()} side termination not found: {device} {name}")
setattr(self.instance, f'termination_{side}', termination_object)
return termination_object