mirror of
https://github.com/netbox-community/netbox.git
synced 2025-09-06 14:23:36 -06:00
Fixes: #19669 - Add an API endpoint to download image attachments
This commit is contained in:
parent
ffa9a52667
commit
f48e1cb534
@ -1,5 +1,7 @@
|
||||
from django.conf import settings
|
||||
from django.http import Http404
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.views.static import serve
|
||||
from django_rq.queues import get_connection
|
||||
from drf_spectacular.utils import extend_schema, extend_schema_view
|
||||
from rest_framework import status
|
||||
@ -32,6 +34,7 @@ class ExtrasRootView(APIRootView):
|
||||
"""
|
||||
Extras API root view
|
||||
"""
|
||||
|
||||
def get_view_name(self):
|
||||
return 'Extras'
|
||||
|
||||
@ -40,6 +43,7 @@ class ExtrasRootView(APIRootView):
|
||||
# EventRules
|
||||
#
|
||||
|
||||
|
||||
class EventRuleViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = EventRule.objects.all()
|
||||
@ -51,6 +55,7 @@ class EventRuleViewSet(NetBoxModelViewSet):
|
||||
# Webhooks
|
||||
#
|
||||
|
||||
|
||||
class WebhookViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = Webhook.objects.all()
|
||||
@ -62,6 +67,7 @@ class WebhookViewSet(NetBoxModelViewSet):
|
||||
# Custom fields
|
||||
#
|
||||
|
||||
|
||||
class CustomFieldViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = CustomField.objects.select_related('choice_set')
|
||||
@ -89,9 +95,7 @@ class CustomFieldChoiceSetViewSet(NetBoxModelViewSet):
|
||||
|
||||
# Paginate data
|
||||
if page := self.paginate_queryset(choices):
|
||||
data = [
|
||||
{'id': c[0], 'display': c[1]} for c in page
|
||||
]
|
||||
data = [{'id': c[0], 'display': c[1]} for c in page]
|
||||
else:
|
||||
data = []
|
||||
|
||||
@ -102,6 +106,7 @@ class CustomFieldChoiceSetViewSet(NetBoxModelViewSet):
|
||||
# Custom links
|
||||
#
|
||||
|
||||
|
||||
class CustomLinkViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = CustomLink.objects.all()
|
||||
@ -113,6 +118,7 @@ class CustomLinkViewSet(NetBoxModelViewSet):
|
||||
# Export templates
|
||||
#
|
||||
|
||||
|
||||
class ExportTemplateViewSet(SyncedDataMixin, NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = ExportTemplate.objects.all()
|
||||
@ -124,6 +130,7 @@ class ExportTemplateViewSet(SyncedDataMixin, NetBoxModelViewSet):
|
||||
# Saved filters
|
||||
#
|
||||
|
||||
|
||||
class SavedFilterViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = SavedFilter.objects.all()
|
||||
@ -135,6 +142,7 @@ class SavedFilterViewSet(NetBoxModelViewSet):
|
||||
# Table Configs
|
||||
#
|
||||
|
||||
|
||||
class TableConfigViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = TableConfig.objects.all()
|
||||
@ -146,6 +154,7 @@ class TableConfigViewSet(NetBoxModelViewSet):
|
||||
# Bookmarks
|
||||
#
|
||||
|
||||
|
||||
class BookmarkViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = Bookmark.objects.all()
|
||||
@ -157,6 +166,7 @@ class BookmarkViewSet(NetBoxModelViewSet):
|
||||
# Notifications & subscriptions
|
||||
#
|
||||
|
||||
|
||||
class NotificationViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = Notification.objects.all()
|
||||
@ -178,6 +188,7 @@ class SubscriptionViewSet(NetBoxModelViewSet):
|
||||
# Tags
|
||||
#
|
||||
|
||||
|
||||
class TagViewSet(NetBoxModelViewSet):
|
||||
queryset = Tag.objects.all()
|
||||
serializer_class = serializers.TagSerializer
|
||||
@ -194,17 +205,30 @@ class TaggedItemViewSet(RetrieveModelMixin, ListModelMixin, BaseViewSet):
|
||||
# Image attachments
|
||||
#
|
||||
|
||||
|
||||
class ImageAttachmentViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = ImageAttachment.objects.all()
|
||||
serializer_class = serializers.ImageAttachmentSerializer
|
||||
filterset_class = filtersets.ImageAttachmentFilterSet
|
||||
|
||||
@action(
|
||||
methods=['GET'],
|
||||
detail=True,
|
||||
url_path='download',
|
||||
url_name='download',
|
||||
)
|
||||
def download(self, request, pk, *args, **kwargs):
|
||||
obj = get_object_or_404(self.queryset, pk=pk)
|
||||
# Render and return the elevation as an SVG drawing with the correct content type
|
||||
return serve(request, obj.image.path, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
|
||||
#
|
||||
# Journal entries
|
||||
#
|
||||
|
||||
|
||||
class JournalEntryViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = JournalEntry.objects.all()
|
||||
@ -216,6 +240,7 @@ class JournalEntryViewSet(NetBoxModelViewSet):
|
||||
# Config contexts
|
||||
#
|
||||
|
||||
|
||||
class ConfigContextViewSet(SyncedDataMixin, NetBoxModelViewSet):
|
||||
queryset = ConfigContext.objects.all()
|
||||
serializer_class = serializers.ConfigContextSerializer
|
||||
@ -226,6 +251,7 @@ class ConfigContextViewSet(SyncedDataMixin, NetBoxModelViewSet):
|
||||
# Config templates
|
||||
#
|
||||
|
||||
|
||||
class ConfigTemplateViewSet(SyncedDataMixin, ConfigTemplateRenderMixin, NetBoxModelViewSet):
|
||||
queryset = ConfigTemplate.objects.all()
|
||||
serializer_class = serializers.ConfigTemplateSerializer
|
||||
@ -247,6 +273,7 @@ class ConfigTemplateViewSet(SyncedDataMixin, ConfigTemplateRenderMixin, NetBoxMo
|
||||
# Scripts
|
||||
#
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
update=extend_schema(request=serializers.ScriptInputSerializer),
|
||||
partial_update=extend_schema(request=serializers.ScriptInputSerializer),
|
||||
@ -287,10 +314,7 @@ class ScriptViewSet(ModelViewSet):
|
||||
raise PermissionDenied("This user does not have permission to run scripts.")
|
||||
|
||||
script = self._get_script(pk)
|
||||
input_serializer = serializers.ScriptInputSerializer(
|
||||
data=request.data,
|
||||
context={'script': script}
|
||||
)
|
||||
input_serializer = serializers.ScriptInputSerializer(data=request.data, context={'script': script})
|
||||
|
||||
# Check that at least one RQ worker is running
|
||||
if not Worker.count(get_connection('default')):
|
||||
@ -305,7 +329,7 @@ class ScriptViewSet(ModelViewSet):
|
||||
commit=input_serializer.data['commit'],
|
||||
job_timeout=script.python_class.job_timeout,
|
||||
schedule_at=input_serializer.validated_data.get('schedule_at'),
|
||||
interval=input_serializer.validated_data.get('interval')
|
||||
interval=input_serializer.validated_data.get('interval'),
|
||||
)
|
||||
serializer = serializers.ScriptDetailSerializer(script, context={'request': request})
|
||||
|
||||
@ -318,10 +342,12 @@ class ScriptViewSet(ModelViewSet):
|
||||
# Object types
|
||||
#
|
||||
|
||||
|
||||
class ObjectTypeViewSet(ReadOnlyModelViewSet):
|
||||
"""
|
||||
Read-only list of ObjectTypes.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticatedOrLoginNotRequired]
|
||||
queryset = ObjectType.objects.order_by('app_label', 'model')
|
||||
serializer_class = serializers.ObjectTypeSerializer
|
||||
@ -332,6 +358,7 @@ class ObjectTypeViewSet(ReadOnlyModelViewSet):
|
||||
# User dashboard
|
||||
#
|
||||
|
||||
|
||||
class DashboardView(RetrieveUpdateDestroyAPIView):
|
||||
queryset = Dashboard.objects.all()
|
||||
serializer_class = serializers.DashboardSerializer
|
||||
|
Loading…
Reference in New Issue
Block a user