class RelationshipSerializer(serializers.ModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:relationship-detail") source_type = ContentTypeField(queryset=ContentType.objects.filter( FeatureQuery("relationships").get_query()), ) destination_type = ContentTypeField(queryset=ContentType.objects.filter( FeatureQuery("relationships").get_query()), ) class Meta: model = Relationship fields = [ "id", "url", "name", "slug", "description", "type", "source_type", "source_label", "source_hidden", "source_filter", "destination_type", "destination_label", "destination_hidden", "destination_filter", ]
class CableSerializer(TaggedObjectSerializer, StatusModelSerializerMixin, CustomFieldModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="dcim-api:cable-detail") termination_a_type = ContentTypeField( queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)) termination_b_type = ContentTypeField( queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)) termination_a = serializers.SerializerMethodField(read_only=True) termination_b = serializers.SerializerMethodField(read_only=True) length_unit = ChoiceField(choices=CableLengthUnitChoices, allow_blank=True, required=False) class Meta: model = Cable fields = [ "id", "url", "termination_a_type", "termination_a_id", "termination_a", "termination_b_type", "termination_b_id", "termination_b", "type", "status", "label", "color", "length", "length_unit", "tags", "custom_fields", "computed_fields", ] opt_in_fields = ["computed_fields"] def _get_termination(self, obj, side): """ Serialize a nested representation of a termination. """ if side.lower() not in ["a", "b"]: raise ValueError("Termination side must be either A or B.") termination = getattr(obj, "termination_{}".format(side.lower())) if termination is None: return None serializer = get_serializer_for_model(termination, prefix="Nested") context = {"request": self.context["request"]} data = serializer(termination, context=context).data return data @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_termination_a(self, obj): return self._get_termination(obj, "a") @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_termination_b(self, obj): return self._get_termination(obj, "b")
class CablePathSerializer(serializers.ModelSerializer): origin_type = ContentTypeField(read_only=True) origin = serializers.SerializerMethodField(read_only=True) destination_type = ContentTypeField(read_only=True) destination = serializers.SerializerMethodField(read_only=True) path = serializers.SerializerMethodField(read_only=True) class Meta: model = CablePath fields = [ "id", "origin_type", "origin", "destination_type", "destination", "path", "is_active", "is_split", ] @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_origin(self, obj): """ Return the appropriate serializer for the origin. """ serializer = get_serializer_for_model(obj.origin, prefix="Nested") context = {"request": self.context["request"]} return serializer(obj.origin, context=context).data @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_destination(self, obj): """ Return the appropriate serializer for the destination, if any. """ if obj.destination_id is not None: serializer = get_serializer_for_model(obj.destination, prefix="Nested") context = {"request": self.context["request"]} return serializer(obj.destination, context=context).data return None @swagger_serializer_method(serializer_or_field=serializers.ListField) def get_path(self, obj): ret = [] for node in obj.get_path(): serializer = get_serializer_for_model(node, prefix="Nested") context = {"request": self.context["request"]} ret.append(serializer(node, context=context).data) return ret
class NestedObjectPermissionSerializer(WritableNestedSerializer): url = serializers.HyperlinkedIdentityField( view_name="users-api:objectpermission-detail") object_types = ContentTypeField(queryset=ContentType.objects.all(), many=True) groups = serializers.SerializerMethodField(read_only=True) users = serializers.SerializerMethodField(read_only=True) class Meta: model = ObjectPermission fields = [ "id", "url", "name", "enabled", "object_types", "groups", "users", "actions", ] def get_groups(self, obj): return [g.name for g in obj.groups.all()] def get_users(self, obj): return [u.username for u in obj.users.all()]
class CustomFieldSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:customfield-detail") content_types = ContentTypeField( queryset=ContentType.objects.filter( FeatureQuery("custom_fields").get_query()), many=True, ) type = ChoiceField(choices=CustomFieldTypeChoices) filter_logic = ChoiceField(choices=CustomFieldFilterLogicChoices, required=False) class Meta: model = CustomField fields = [ "id", "url", "content_types", "type", "name", "label", "description", "required", "filter_logic", "default", "weight", "validation_minimum", "validation_maximum", "validation_regex", ]
class WebhookSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:webhook-detail") content_types = ContentTypeField( queryset=ContentType.objects.filter( FeatureQuery("webhooks").get_query()).order_by( "app_label", "model"), many=True, ) class Meta: model = Webhook fields = [ "id", "url", "content_types", "name", "type_create", "type_update", "type_delete", "payload_url", "http_method", "http_content_type", "additional_headers", "body_template", "secret", "ssl_verification", "ca_file_path", ]
class JobResultSerializer(serializers.ModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:jobresult-detail") user = NestedUserSerializer(read_only=True) status = ChoiceField(choices=JobResultStatusChoices, read_only=True) job_model = NestedJobSerializer(read_only=True) obj_type = ContentTypeField(read_only=True) schedule = NestedScheduledJobSerializer(read_only=True) class Meta: model = JobResult fields = [ "id", "url", "created", "completed", "name", "job_model", "obj_type", "status", "user", "data", "job_id", "schedule", ]
class ConfigContextSchemaSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:configcontextschema-detail") owner_content_type = ContentTypeField( queryset=ContentType.objects.filter( FeatureQuery("config_context_owners").get_query()), required=False, allow_null=True, default=None, ) owner = serializers.SerializerMethodField(read_only=True) class Meta: model = ConfigContextSchema fields = [ "id", "url", "name", "slug", "owner_content_type", "owner_object_id", "owner", "description", "data_schema", "created", "last_updated", ] @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_owner(self, obj): if obj.owner is None: return None serializer = get_serializer_for_model(obj.owner, prefix="Nested") context = {"request": self.context["request"]} return serializer(obj.owner, context=context).data
class ObjectPermissionSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="users-api:objectpermission-detail") object_types = ContentTypeField(queryset=ContentType.objects.all(), many=True) groups = SerializedPKRelatedField( queryset=Group.objects.all(), serializer=NestedGroupSerializer, required=False, many=True, ) users = SerializedPKRelatedField( queryset=get_user_model().objects.all(), serializer=NestedUserSerializer, required=False, many=True, ) class Meta: model = ObjectPermission fields = ( "id", "url", "name", "description", "enabled", "object_types", "groups", "users", "actions", "constraints", )
class NestedCustomLinkSerializer(WritableNestedSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:customlink-detail") content_type = ContentTypeField(queryset=ContentType.objects.all(), ) class Meta: model = models.CustomLink fields = ["content_type", "id", "name", "url"]
class NestedDynamicGroupSerializer(WritableNestedSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:dynamicgroup-detail") content_type = ContentTypeField(queryset=ContentType.objects.all(), ) class Meta: model = models.DynamicGroup fields = ["id", "url", "name", "slug", "content_type"]
class IPAddressSerializer(TaggedObjectSerializer, StatusModelSerializerMixin, CustomFieldModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="ipam-api:ipaddress-detail") family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True) address = IPFieldSerializer() vrf = NestedVRFSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True) role = ChoiceField(choices=IPAddressRoleChoices, allow_blank=True, required=False) assigned_object_type = ContentTypeField( queryset=ContentType.objects.filter( constants.IPADDRESS_ASSIGNMENT_MODELS), required=False, allow_null=True, ) assigned_object = serializers.SerializerMethodField(read_only=True) nat_inside = NestedIPAddressSerializer(required=False, allow_null=True) nat_outside = NestedIPAddressSerializer(read_only=True) class Meta: model = IPAddress fields = [ "id", "url", "family", "address", "vrf", "tenant", "status", "role", "assigned_object_type", "assigned_object_id", "assigned_object", "nat_inside", "nat_outside", "dns_name", "description", "tags", "custom_fields", "created", "last_updated", "computed_fields", ] read_only_fields = ["family"] opt_in_fields = ["computed_fields"] @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_assigned_object(self, obj): if obj.assigned_object is None: return None serializer = get_serializer_for_model(obj.assigned_object, prefix="Nested") context = {"request": self.context["request"]} return serializer(obj.assigned_object, context=context).data
class ImageAttachmentSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:imageattachment-detail") content_type = ContentTypeField(queryset=ContentType.objects.all()) parent = serializers.SerializerMethodField(read_only=True) class Meta: model = ImageAttachment fields = [ "id", "url", "content_type", "object_id", "parent", "name", "image", "image_height", "image_width", "created", ] def validate(self, data): # Validate that the parent object exists try: data["content_type"].get_object_for_this_type(id=data["object_id"]) except ObjectDoesNotExist: raise serializers.ValidationError( "Invalid parent object: {} ID {}".format( data["content_type"], data["object_id"])) # Enforce model validation super().validate(data) return data @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_parent(self, obj): # Static mapping of models to their nested serializers if isinstance(obj.parent, Device): serializer = NestedDeviceSerializer elif isinstance(obj.parent, Rack): serializer = NestedRackSerializer elif isinstance(obj.parent, Site): serializer = NestedSiteSerializer else: raise Exception( "Unexpected type of parent object for ImageAttachment") return serializer(obj.parent, context={ "request": self.context["request"] }).data
class RelationshipAssociationSerializer(serializers.ModelSerializer): source_type = ContentTypeField(queryset=ContentType.objects.filter( FeatureQuery("relationships").get_query()), ) destination_type = ContentTypeField(queryset=ContentType.objects.filter( FeatureQuery("relationships").get_query()), ) relationship = NestedRelationshipSerializer() class Meta: model = RelationshipAssociation fields = [ "id", "relationship", "source_type", "source_id", "destination_type", "destination_id", ]
class ExportTemplateSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:exporttemplate-detail") content_type = ContentTypeField(queryset=ContentType.objects.filter( FeatureQuery("export_templates").get_query()), ) owner_content_type = ContentTypeField( queryset=ContentType.objects.filter( FeatureQuery("export_template_owners").get_query()), required=False, allow_null=True, default=None, ) owner = serializers.SerializerMethodField(read_only=True) class Meta: model = ExportTemplate fields = [ "id", "url", "content_type", "owner_content_type", "owner_object_id", "owner", "name", "description", "template_code", "mime_type", "file_extension", ] @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_owner(self, obj): if obj.owner is None: return None serializer = get_serializer_for_model(obj.owner, prefix="Nested") context = {"request": self.context["request"]} return serializer(obj.owner, context=context).data
class WebhookSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:webhook-detail") content_types = ContentTypeField( queryset=ContentType.objects.filter( FeatureQuery("webhooks").get_query()).order_by( "app_label", "model"), many=True, ) class Meta: model = Webhook fields = [ "id", "url", "content_types", "name", "type_create", "type_update", "type_delete", "payload_url", "http_method", "http_content_type", "additional_headers", "body_template", "secret", "ssl_verification", "ca_file_path", ] def validate(self, data): validated_data = super().validate(data) conflicts = Webhook.check_for_conflicts( instance=self.instance, content_types=data.get("content_types"), payload_url=data.get("payload_url"), type_create=data.get("type_create"), type_update=data.get("type_update"), type_delete=data.get("type_delete"), ) if conflicts: raise serializers.ValidationError(conflicts) return validated_data
class ComputedFieldSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="extras-api:computedfield-detail") content_type = ContentTypeField( queryset=ContentType.objects.filter(FeatureQuery("custom_fields").get_query()).order_by("app_label", "model"), ) class Meta: model = ComputedField fields = ( "id", "url", "slug", "label", "description", "content_type", "template", "fallback_value", "weight", )
class DynamicGroupSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:dynamicgroup-detail") content_type = ContentTypeField(queryset=ContentType.objects.filter( FeatureQuery("dynamic_groups").get_query()).order_by( "app_label", "model"), ) class Meta: model = DynamicGroup fields = [ "id", "url", "name", "slug", "description", "content_type", "filter", ] extra_kwargs = {"filter": {"read_only": False}}
class CustomLinkSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="extras-api:customlink-detail") content_type = ContentTypeField( queryset=ContentType.objects.filter(FeatureQuery("custom_links").get_query()).order_by("app_label", "model"), ) class Meta: model = CustomLink fields = ( "id", "url", "target_url", "name", "content_type", "text", "weight", "group_name", "button_class", "new_window", )
class ObjectChangeSerializer(serializers.ModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:objectchange-detail") user = NestedUserSerializer(read_only=True) action = ChoiceField(choices=ObjectChangeActionChoices, read_only=True) changed_object_type = ContentTypeField(read_only=True) changed_object = serializers.SerializerMethodField(read_only=True) class Meta: model = ObjectChange fields = [ "id", "url", "time", "user", "user_name", "request_id", "action", "changed_object_type", "changed_object_id", "changed_object", "object_data", ] @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_changed_object(self, obj): """ Serialize a nested representation of the changed object. """ if obj.changed_object is None: return None try: serializer = get_serializer_for_model(obj.changed_object, prefix="Nested") except SerializerNotFound: return obj.object_repr context = {"request": self.context["request"]} data = serializer(obj.changed_object, context=context).data return data
class TagSerializerVersion13(TagSerializer): content_types = ContentTypeField( queryset=TaggableClassesQuery().as_queryset, many=True, required=True, ) class Meta: model = Tag fields = [ "id", "url", "name", "slug", "color", "description", "tagged_items", "content_types", "custom_fields", "created", "last_updated", ]
class StatusSerializer(CustomFieldModelSerializer): """Serializer for `Status` objects.""" url = serializers.HyperlinkedIdentityField(view_name="extras-api:status-detail") content_types = ContentTypeField( queryset=ContentType.objects.filter(FeatureQuery("statuses").get_query()), many=True, ) class Meta: model = Status fields = [ "id", "url", "content_types", "name", "slug", "color", "custom_fields", "created", "last_updated", ]
class ConfigContextSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name="extras-api:configcontext-detail") owner_content_type = ContentTypeField( queryset=ContentType.objects.filter( FeatureQuery("config_context_owners").get_query()), required=False, allow_null=True, default=None, ) owner = serializers.SerializerMethodField(read_only=True) schema = NestedConfigContextSchemaSerializer(required=False, allow_null=True) regions = SerializedPKRelatedField( queryset=Region.objects.all(), serializer=NestedRegionSerializer, required=False, many=True, ) sites = SerializedPKRelatedField( queryset=Site.objects.all(), serializer=NestedSiteSerializer, required=False, many=True, ) roles = SerializedPKRelatedField( queryset=DeviceRole.objects.all(), serializer=NestedDeviceRoleSerializer, required=False, many=True, ) device_types = SerializedPKRelatedField( queryset=DeviceType.objects.all(), serializer=NestedDeviceRoleSerializer, required=False, many=True, ) platforms = SerializedPKRelatedField( queryset=Platform.objects.all(), serializer=NestedPlatformSerializer, required=False, many=True, ) cluster_groups = SerializedPKRelatedField( queryset=ClusterGroup.objects.all(), serializer=NestedClusterGroupSerializer, required=False, many=True, ) clusters = SerializedPKRelatedField( queryset=Cluster.objects.all(), serializer=NestedClusterSerializer, required=False, many=True, ) tenant_groups = SerializedPKRelatedField( queryset=TenantGroup.objects.all(), serializer=NestedTenantGroupSerializer, required=False, many=True, ) tenants = SerializedPKRelatedField( queryset=Tenant.objects.all(), serializer=NestedTenantSerializer, required=False, many=True, ) tags = serializers.SlugRelatedField(queryset=Tag.objects.all(), slug_field="slug", required=False, many=True) class Meta: model = ConfigContext fields = [ "id", "url", "name", "owner_content_type", "owner_object_id", "owner", "weight", "description", "schema", "is_active", "regions", "sites", "roles", "device_types", "platforms", "cluster_groups", "clusters", "tenant_groups", "tenants", "tags", "data", "created", "last_updated", ] @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_owner(self, obj): if obj.owner is None: return None serializer = get_serializer_for_model(obj.owner, prefix="Nested") context = {"request": self.context["request"]} return serializer(obj.owner, context=context).data