1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Implemented API endpoints for ImageAttachments

This commit is contained in:
Jeremy Stretch
2017-04-03 14:00:15 -04:00
parent 6bbdc2bae1
commit 2c1fa628a2
6 changed files with 83 additions and 7 deletions

View File

@ -1,9 +1,14 @@
from rest_framework import serializers from rest_framework import serializers
from dcim.api.serializers import NestedSiteSerializer from django.core.exceptions import ObjectDoesNotExist
from extras.models import ACTION_CHOICES, Graph, GRAPH_TYPE_CHOICES, ExportTemplate, TopologyMap, UserAction
from dcim.api.serializers import NestedDeviceSerializer, NestedRackSerializer, NestedSiteSerializer
from dcim.models import Device, Rack, Site
from extras.models import (
ACTION_CHOICES, ExportTemplate, Graph, GRAPH_TYPE_CHOICES, ImageAttachment, TopologyMap, UserAction,
)
from users.api.serializers import NestedUserSerializer from users.api.serializers import NestedUserSerializer
from utilities.api import ChoiceFieldSerializer from utilities.api import ChoiceFieldSerializer, ContentTypeFieldSerializer
# #
@ -71,6 +76,52 @@ class WritableTopologyMapSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug', 'site', 'device_patterns', 'description'] fields = ['id', 'name', 'slug', 'site', 'device_patterns', 'description']
#
# Image attachments
#
class ImageAttachmentSerializer(serializers.ModelSerializer):
parent = serializers.SerializerMethodField()
class Meta:
model = ImageAttachment
fields = ['id', 'parent', 'name', 'image', 'image_height', 'image_width', 'created']
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 WritableImageAttachmentSerializer(serializers.ModelSerializer):
content_type = ContentTypeFieldSerializer()
class Meta:
model = ImageAttachment
fields = ['id', 'content_type', 'object_id', 'name', 'image']
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'])
)
return data
# #
# User actions # User actions
# #

View File

@ -23,6 +23,9 @@ router.register(r'export-templates', views.ExportTemplateViewSet)
# Topology maps # Topology maps
router.register(r'topology-maps', views.TopologyMapViewSet) router.register(r'topology-maps', views.TopologyMapViewSet)
# Image attachments
router.register(r'image-attachments', views.ImageAttachmentViewSet)
# Recent activity # Recent activity
router.register(r'recent-activity', views.RecentActivityViewSet) router.register(r'recent-activity', views.RecentActivityViewSet)

View File

@ -6,7 +6,7 @@ from django.http import HttpResponse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from extras import filters from extras import filters
from extras.models import ExportTemplate, Graph, TopologyMap, UserAction from extras.models import ExportTemplate, Graph, ImageAttachment, TopologyMap, UserAction
from utilities.api import WritableSerializerMixin from utilities.api import WritableSerializerMixin
from . import serializers from . import serializers
@ -81,6 +81,12 @@ class TopologyMapViewSet(WritableSerializerMixin, ModelViewSet):
return response return response
class ImageAttachmentViewSet(WritableSerializerMixin, ModelViewSet):
queryset = ImageAttachment.objects.all()
serializer_class = serializers.ImageAttachmentSerializer
write_serializer_class = serializers.WritableImageAttachmentSerializer
class RecentActivityViewSet(ReadOnlyModelViewSet): class RecentActivityViewSet(ReadOnlyModelViewSet):
""" """
List all UserActions to provide a log of recent activity. List all UserActions to provide a log of recent activity.

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.10.6 on 2017-03-30 21:09 # Generated by Django 1.10.6 on 2017-04-03 15:55
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models

View File

@ -384,7 +384,7 @@ class ImageAttachment(models.Model):
""" """
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
obj = GenericForeignKey('content_type', 'object_id') parent = GenericForeignKey('content_type', 'object_id')
image = models.ImageField(upload_to=image_upload, height_field='image_height', width_field='image_width') image = models.ImageField(upload_to=image_upload, height_field='image_height', width_field='image_width')
image_height = models.PositiveSmallIntegerField() image_height = models.PositiveSmallIntegerField()
image_width = models.PositiveSmallIntegerField() image_width = models.PositiveSmallIntegerField()

View File

@ -1,9 +1,10 @@
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from rest_framework import authentication, exceptions from rest_framework import authentication, exceptions
from rest_framework.exceptions import APIException from rest_framework.exceptions import APIException
from rest_framework.permissions import DjangoModelPermissions, SAFE_METHODS from rest_framework.permissions import DjangoModelPermissions, SAFE_METHODS
from rest_framework.serializers import Field from rest_framework.serializers import Field, ValidationError
from users.models import Token from users.models import Token
@ -79,6 +80,21 @@ class ChoiceFieldSerializer(Field):
return self._choices.get(data) return self._choices.get(data)
class ContentTypeFieldSerializer(Field):
"""
Represent a ContentType as '<app_label>.<model>'
"""
def to_representation(self, obj):
return "{}.{}".format(obj.app_label, obj.model)
def to_internal_value(self, data):
app_label, model = data.split('.')
try:
return ContentType.objects.get_by_natural_key(app_label=app_label, model=model)
except ContentType.DoesNotExist:
raise ValidationError("Invalid content type")
class WritableSerializerMixin(object): class WritableSerializerMixin(object):
""" """
Allow for the use of an alternate, writable serializer class for write operations (e.g. POST, PUT). Allow for the use of an alternate, writable serializer class for write operations (e.g. POST, PUT).