diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 2856c5a48..16e800e70 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#4905](https://github.com/netbox-community/netbox/issues/4905) - Fix front port count on device type view +* [#4912](https://github.com/netbox-community/netbox/issues/4912) - Fix image attachment API endpoint --- diff --git a/netbox/extras/api/nested_serializers.py b/netbox/extras/api/nested_serializers.py index e3fb2e0db..198a5d2f8 100644 --- a/netbox/extras/api/nested_serializers.py +++ b/netbox/extras/api/nested_serializers.py @@ -8,6 +8,7 @@ __all__ = [ 'NestedConfigContextSerializer', 'NestedExportTemplateSerializer', 'NestedGraphSerializer', + 'NestedImageAttachmentSerializer', 'NestedJobResultSerializer', 'NestedTagSerializer', ] @@ -37,6 +38,14 @@ class NestedGraphSerializer(WritableNestedSerializer): fields = ['id', 'url', 'name'] +class NestedImageAttachmentSerializer(WritableNestedSerializer): + url = serializers.HyperlinkedIdentityField(view_name='extras-api:imageattachment-detail') + + class Meta: + model = models.ImageAttachment + fields = ['id', 'url', 'name', 'image'] + + class NestedTagSerializer(WritableNestedSerializer): url = serializers.HyperlinkedIdentityField(view_name='extras-api:tag-detail') diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 9b6de22c6..9b5c77fcb 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -387,6 +387,8 @@ class ImageAttachment(models.Model): auto_now_add=True ) + objects = RestrictedQuerySet.as_manager() + class Meta: ordering = ('name', 'pk') # name may be non-unique diff --git a/netbox/extras/tests/test_api.py b/netbox/extras/tests/test_api.py index fccb03665..c768534a2 100644 --- a/netbox/extras/tests/test_api.py +++ b/netbox/extras/tests/test_api.py @@ -10,7 +10,7 @@ from rq import Worker from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Rack, RackGroup, RackRole, Site from extras.api.views import ReportViewSet, ScriptViewSet -from extras.models import ConfigContext, Graph, ExportTemplate, Tag +from extras.models import ConfigContext, ExportTemplate, Graph, ImageAttachment, Tag from extras.reports import Report from extras.scripts import BooleanVar, IntegerVar, Script, StringVar from utilities.testing import APITestCase, APIViewTestCases @@ -136,6 +136,50 @@ class TagTest(APIViewTestCases.APIViewTestCase): Tag.objects.bulk_create(tags) +# TODO: Standardize to APIViewTestCase (needs create & update tests) +class ImageAttachmentTest( + APIViewTestCases.GetObjectViewTestCase, + APIViewTestCases.ListObjectsViewTestCase, + APIViewTestCases.DeleteObjectViewTestCase +): + model = ImageAttachment + brief_fields = ['id', 'image', 'name', 'url'] + + @classmethod + def setUpTestData(cls): + ct = ContentType.objects.get_for_model(Site) + + site = Site.objects.create(name='Site 1', slug='site-1') + + image_attachments = ( + ImageAttachment( + content_type=ct, + object_id=site.pk, + name='Image Attachment 1', + image='http://example.com/image1.png', + image_height=100, + image_width=100 + ), + ImageAttachment( + content_type=ct, + object_id=site.pk, + name='Image Attachment 2', + image='http://example.com/image2.png', + image_height=100, + image_width=100 + ), + ImageAttachment( + content_type=ct, + object_id=site.pk, + name='Image Attachment 3', + image='http://example.com/image3.png', + image_height=100, + image_width=100 + ) + ) + ImageAttachment.objects.bulk_create(image_attachments) + + class ConfigContextTest(APIViewTestCases.APIViewTestCase): model = ConfigContext brief_fields = ['id', 'name', 'url']