mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
dcim: add rack-elevations api endpoint (references #2248)
This commit is contained in:
parent
88c7d95b08
commit
d11de6d021
@ -25,6 +25,7 @@ router.register(r'sites', views.SiteViewSet)
|
||||
router.register(r'rack-groups', views.RackGroupViewSet)
|
||||
router.register(r'rack-roles', views.RackRoleViewSet)
|
||||
router.register(r'racks', views.RackViewSet)
|
||||
router.register(r'rack-elevations', views.RackElevationViewSet, basename='rack-elevation')
|
||||
router.register(r'rack-reservations', views.RackReservationViewSet)
|
||||
|
||||
# Device types
|
||||
|
@ -1,9 +1,11 @@
|
||||
from collections import OrderedDict
|
||||
|
||||
import svgwrite
|
||||
from django.conf import settings
|
||||
from django.db.models import Count, F
|
||||
from django.http import HttpResponseForbidden
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.http import HttpResponseForbidden, HttpResponse
|
||||
from django.shortcuts import get_object_or_404, reverse
|
||||
from django.utils.http import urlencode
|
||||
from drf_yasg import openapi
|
||||
from drf_yasg.openapi import Parameter
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
@ -201,6 +203,46 @@ class RackViewSet(CustomFieldModelViewSet):
|
||||
return self.get_paginated_response(rack_units.data)
|
||||
|
||||
|
||||
class RackElevationViewSet(ViewSet):
|
||||
queryset = Rack.objects.prefetch_related(
|
||||
'devices'
|
||||
)
|
||||
|
||||
def get_view_name(self):
|
||||
return "Rack Elevations"
|
||||
|
||||
|
||||
def retrieve(self, request, pk=None):
|
||||
"""
|
||||
Render rack
|
||||
"""
|
||||
rack = get_object_or_404(Rack, pk=pk)
|
||||
|
||||
elevation = rack.get_front_elevation()
|
||||
drawing = svgwrite.Drawing(size=(230, len(elevation)*20), style="box-sizing: border-box")
|
||||
|
||||
for i, u in enumerate(elevation):
|
||||
device = u['device']
|
||||
start = i * 20
|
||||
end = 20
|
||||
if device:
|
||||
link = drawing.add(drawing.a(reverse('dcim:device', kwargs={'pk': device.pk}), fill='black'))
|
||||
link.add(drawing.rect((0, start), (230, end), fill='#{}'.format(device.device_role.color), stroke='grey'))
|
||||
link.add(drawing.text(device.name, insert=(0, start+20)))
|
||||
else:
|
||||
link = drawing.add(
|
||||
drawing.a('{}?{}'.format(
|
||||
reverse('dcim:device_add'),
|
||||
urlencode({'rack': rack.pk, 'site': rack.site.pk, 'face': 0, 'position': u['id']})
|
||||
))
|
||||
)
|
||||
link.add(drawing.rect((0, start), (230, end), fill='white', stroke='lightgrey'))
|
||||
|
||||
drawing.add(drawing.rect((0, 0), (230, len(elevation*20)), stroke='black', stroke_width=3, fill='none'))
|
||||
|
||||
return HttpResponse(drawing.tostring(), content_type='image/svg+xml')
|
||||
|
||||
|
||||
#
|
||||
# Rack reservations
|
||||
#
|
||||
|
@ -419,8 +419,6 @@ class RackView(PermissionRequiredMixin, View):
|
||||
'nonracked_devices': nonracked_devices,
|
||||
'next_rack': next_rack,
|
||||
'prev_rack': prev_rack,
|
||||
'front_elevation': rack.get_front_elevation(),
|
||||
'rear_elevation': rack.get_rear_elevation(),
|
||||
})
|
||||
|
||||
|
||||
|
@ -8,47 +8,6 @@
|
||||
|
||||
<div class="rack_frame">
|
||||
|
||||
<!-- Render rear view of devices on far face -->
|
||||
<ul class="rack rack_far_face">
|
||||
{% for u in secondary_face %}
|
||||
{% if u.device %}
|
||||
<li class="occupied h{{ u.device.device_type.u_height }}u{% if u.device.device_type.is_full_depth %} blocked{% endif %}"></li>
|
||||
{% else %}
|
||||
<li></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<!-- Render front view of devices on near face -->
|
||||
<ul class="rack rack_near_face">
|
||||
{% for u in primary_face %}
|
||||
{% if u.device %}
|
||||
<li class="occupied h{{ u.device.device_type.u_height }}u"{% ifequal u.device.face face_id %} style="background-color: #{{ u.device.device_role.color }}"{% endifequal %}>
|
||||
{% ifequal u.device.face face_id %}
|
||||
<a href="{% url 'dcim:device' pk=u.device.pk %}" style="color: {{ u.device.device_role.color|fgcolor }}" data-toggle="popover" data-trigger="hover" data-container="body" data-html="true"
|
||||
data-content="{{ u.device.device_role }}<br />{{ u.device.device_type.display_name }} ({{ u.device.device_type.u_height }}U){% if u.device.asset_tag %}<br />{{ u.device.asset_tag }}{% endif %}{% if u.device.serial %}<br />{{ u.device.serial }}{% endif %}">
|
||||
{{ u.device }}
|
||||
{% if u.device.devicebay_count %}
|
||||
({{ u.device.get_children.count }}/{{ u.device.devicebay_count }})
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<span>{{ u.device }}</span>
|
||||
{% endifequal %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="available{% if u.id in reserved_units.keys %} reserved{% endif %}">
|
||||
{% if perms.dcim.add_device %}
|
||||
<a href="{% url 'dcim:device_add' %}?site={{ rack.site.pk }}&rack={{ rack.pk }}&face={{ face_id }}&position={{ u.id }}" class="add_device"
|
||||
{% if u.id in reserved_units.keys %}{% with reserved_units|getkey:u.id as resv %}
|
||||
data-toggle="popover" data-trigger="hover" data-container="body" data-html="true"
|
||||
data-content="{{ resv.description }}<br/><small>{{ resv.user }} · {{ resv.created }}</small>"
|
||||
{% endwith %}{% endif %}
|
||||
>add device</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<img src="{% url 'dcim-api:rack-elevation-detail' pk=rack.pk %}" height="100%">
|
||||
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user