ObjectMetadata-Backed Fields (ObjectMetadataAnnotation)¶
ObjectMetadataAnnotation marks a DiffSync model field whose value lives in Nautobot
ObjectMetadata instead of a model field or custom field. Use it to persist an external
system's identifier (e.g. a record ID) on a Nautobot object so future syncs can correlate
the two records.
Usage¶
from typing import Annotated, Optional
from nautobot.dcim.models import Manufacturer
from nautobot_ssot.contrib import NautobotModel, ObjectMetadataAnnotation
class ManufacturerModel(NautobotModel):
_model = Manufacturer
_modelname = "manufacturer"
_identifiers = ("name",)
_attributes = ("external_id",)
name: str
external_id: Annotated[
Optional[str], ObjectMetadataAnnotation(metadata_type_name="External System ID")
] = None
On load, external_id is read from the object's ObjectMetadata of type
"External System ID". On create/update, the value is written back to that metadata (one
whole-object row per annotated field).
Prerequisite: the MetadataType is integration-owned¶
Like CustomFieldAnnotation and CustomRelationshipAnnotation, contrib does not create
the backing schema. Your integration must create the MetadataType and attach the relevant
content type(s) before syncing (e.g. in a prerequisite step or migration):
from django.contrib.contenttypes.models import ContentType
from nautobot.dcim.models import Manufacturer
from nautobot.extras.models.metadata import MetadataType
metadata_type, _ = MetadataType.objects.get_or_create(
name="External System ID", defaults={"data_type": "text"}
)
metadata_type.content_types.add(ContentType.objects.get_for_model(Manufacturer))
Reads are lenient (missing type or row resolves to None). Writes are strict: a missing or
misconfigured MetadataType raises ObjectCrudException. A None value is a no-op
(existing metadata is left unchanged; syncing None does not clear it).