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

Reworked relationship between devices and clusters

This commit is contained in:
Jeremy Stretch
2017-08-16 17:21:34 -04:00
parent 9acd792abe
commit a02055e9b5
7 changed files with 53 additions and 7 deletions

View File

@ -16,6 +16,7 @@ from dcim.models import (
from extras.api.customfields import CustomFieldModelSerializer from extras.api.customfields import CustomFieldModelSerializer
from tenancy.api.serializers import NestedTenantSerializer from tenancy.api.serializers import NestedTenantSerializer
from utilities.api import ChoiceFieldSerializer, ValidatedModelSerializer from utilities.api import ChoiceFieldSerializer, ValidatedModelSerializer
from virtualization.models import Cluster
# #
@ -446,6 +447,15 @@ class DeviceIPAddressSerializer(serializers.ModelSerializer):
fields = ['id', 'url', 'family', 'address'] fields = ['id', 'url', 'family', 'address']
# Cannot import virtualization.api.NestedClusterSerializer due to circular dependency
class NestedClusterSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:cluster-detail')
class Meta:
model = Cluster
fields = ['id', 'url', 'name']
class DeviceSerializer(CustomFieldModelSerializer): class DeviceSerializer(CustomFieldModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
device_role = NestedDeviceRoleSerializer() device_role = NestedDeviceRoleSerializer()
@ -459,13 +469,14 @@ class DeviceSerializer(CustomFieldModelSerializer):
primary_ip4 = DeviceIPAddressSerializer() primary_ip4 = DeviceIPAddressSerializer()
primary_ip6 = DeviceIPAddressSerializer() primary_ip6 = DeviceIPAddressSerializer()
parent_device = serializers.SerializerMethodField() parent_device = serializers.SerializerMethodField()
cluster = NestedClusterSerializer()
class Meta: class Meta:
model = Device model = Device
fields = [ fields = [
'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6', 'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6',
'comments', 'custom_fields', 'cluster', 'comments', 'custom_fields',
] ]
def get_parent_device(self, obj): def get_parent_device(self, obj):

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-08-16 21:06
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('virtualization', '0001_initial'),
('dcim', '0041_napalm_integration'),
]
operations = [
migrations.AddField(
model_name='device',
name='cluster',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='virtualization.Cluster'),
),
]

View File

@ -808,6 +808,13 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
'ipam.IPAddress', related_name='primary_ip6_for', on_delete=models.SET_NULL, blank=True, null=True, 'ipam.IPAddress', related_name='primary_ip6_for', on_delete=models.SET_NULL, blank=True, null=True,
verbose_name='Primary IPv6' verbose_name='Primary IPv6'
) )
cluster = models.ForeignKey(
to='virtualization.Cluster',
on_delete=models.SET_NULL,
related_name='devices',
blank=True,
null=True
)
comments = models.TextField(blank=True) comments = models.TextField(blank=True)
custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id') custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id')
images = GenericRelation(ImageAttachment) images = GenericRelation(ImageAttachment)

View File

@ -4,6 +4,13 @@
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col-sm-8 col-md-9"> <div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{{ cluster.type.get_absolute_url }}">{{ cluster.type }}</a></li>
{% if cluster.group %}
<li><a href="{{ cluster.group.get_absolute_url }}">{{ cluster.group }}</a></li>
{% endif %}
<li>{{ cluster }}</li>
</ol>
</div> </div>
<div class="col-sm-4 col-md-3"> <div class="col-sm-4 col-md-3">
<form action="{% url 'virtualization:cluster_list' %}" method="get"> <form action="{% url 'virtualization:cluster_list' %}" method="get">

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-08-16 19:27 # Generated by Django 1.11.4 on 2017-08-16 21:06
from __future__ import unicode_literals from __future__ import unicode_literals
import dcim.fields import dcim.fields
@ -13,9 +13,9 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('ipam', '0018_remove_service_uniqueness_constraint'),
('tenancy', '0003_unicode_literals'), ('tenancy', '0003_unicode_literals'),
('dcim', '0041_napalm_integration'), ('dcim', '0041_napalm_integration'),
('ipam', '0018_remove_service_uniqueness_constraint'),
] ]
operations = [ operations = [
@ -27,7 +27,6 @@ class Migration(migrations.Migration):
('last_updated', models.DateTimeField(auto_now=True)), ('last_updated', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=100, unique=True)), ('name', models.CharField(max_length=100, unique=True)),
('comments', models.TextField(blank=True)), ('comments', models.TextField(blank=True)),
('devices', models.ManyToManyField(to='dcim.Device')),
], ],
options={ options={
'ordering': ['name'], 'ordering': ['name'],

View File

@ -89,9 +89,6 @@ class Cluster(CreatedUpdatedModel, CustomFieldModel):
blank=True, blank=True,
null=True null=True
) )
devices = models.ManyToManyField(
to='dcim.Device'
)
comments = models.TextField( comments = models.TextField(
blank=True blank=True
) )

View File

@ -6,6 +6,7 @@ from django.shortcuts import get_object_or_404, render
from django.urls import reverse from django.urls import reverse
from django.views.generic import View from django.views.generic import View
from dcim.models import Device
from utilities.views import ( from utilities.views import (
BulkDeleteView, BulkEditView, BulkImportView, ComponentCreateView, ComponentDeleteView, ComponentEditView, BulkDeleteView, BulkEditView, BulkImportView, ComponentCreateView, ComponentDeleteView, ComponentEditView,
ObjectDeleteView, ObjectEditView, ObjectListView, ObjectDeleteView, ObjectEditView, ObjectListView,
@ -95,9 +96,11 @@ class ClusterView(View):
def get(self, request, pk): def get(self, request, pk):
cluster = get_object_or_404(Cluster, pk=pk) cluster = get_object_or_404(Cluster, pk=pk)
devices = Device.objects.filter(cluster=cluster)
return render(request, 'virtualization/cluster.html', { return render(request, 'virtualization/cluster.html', {
'cluster': cluster, 'cluster': cluster,
'devices': devices,
}) })