mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Prefetch the Tenant Group in views which allows its table to be configured by the user. This decreases the amount of database queries that are required to fetch the data.
324 lines
9.9 KiB
Python
324 lines
9.9 KiB
Python
from django.contrib import messages
|
|
from django.db import transaction
|
|
from django.db.models import Q
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
|
|
from netbox.views import generic
|
|
from utilities.forms import ConfirmationForm
|
|
from utilities.utils import count_related
|
|
from . import filtersets, forms, tables
|
|
from .models import *
|
|
|
|
|
|
#
|
|
# Providers
|
|
#
|
|
|
|
class ProviderListView(generic.ObjectListView):
|
|
queryset = Provider.objects.annotate(
|
|
count_circuits=count_related(Circuit, 'provider')
|
|
)
|
|
filterset = filtersets.ProviderFilterSet
|
|
filterset_form = forms.ProviderFilterForm
|
|
table = tables.ProviderTable
|
|
|
|
|
|
class ProviderView(generic.ObjectView):
|
|
queryset = Provider.objects.all()
|
|
|
|
def get_extra_context(self, request, instance):
|
|
circuits = Circuit.objects.restrict(request.user, 'view').filter(
|
|
provider=instance
|
|
).prefetch_related(
|
|
'type', 'tenant', 'tenant__group', 'terminations__site'
|
|
)
|
|
circuits_table = tables.CircuitTable(circuits, user=request.user, exclude=('provider',))
|
|
circuits_table.configure(request)
|
|
|
|
return {
|
|
'circuits_table': circuits_table,
|
|
}
|
|
|
|
|
|
class ProviderEditView(generic.ObjectEditView):
|
|
queryset = Provider.objects.all()
|
|
form = forms.ProviderForm
|
|
|
|
|
|
class ProviderDeleteView(generic.ObjectDeleteView):
|
|
queryset = Provider.objects.all()
|
|
|
|
|
|
class ProviderBulkImportView(generic.BulkImportView):
|
|
queryset = Provider.objects.all()
|
|
model_form = forms.ProviderCSVForm
|
|
table = tables.ProviderTable
|
|
|
|
|
|
class ProviderBulkEditView(generic.BulkEditView):
|
|
queryset = Provider.objects.annotate(
|
|
count_circuits=count_related(Circuit, 'provider')
|
|
)
|
|
filterset = filtersets.ProviderFilterSet
|
|
table = tables.ProviderTable
|
|
form = forms.ProviderBulkEditForm
|
|
|
|
|
|
class ProviderBulkDeleteView(generic.BulkDeleteView):
|
|
queryset = Provider.objects.annotate(
|
|
count_circuits=count_related(Circuit, 'provider')
|
|
)
|
|
filterset = filtersets.ProviderFilterSet
|
|
table = tables.ProviderTable
|
|
|
|
|
|
#
|
|
# Provider networks
|
|
#
|
|
|
|
class ProviderNetworkListView(generic.ObjectListView):
|
|
queryset = ProviderNetwork.objects.all()
|
|
filterset = filtersets.ProviderNetworkFilterSet
|
|
filterset_form = forms.ProviderNetworkFilterForm
|
|
table = tables.ProviderNetworkTable
|
|
|
|
|
|
class ProviderNetworkView(generic.ObjectView):
|
|
queryset = ProviderNetwork.objects.all()
|
|
|
|
def get_extra_context(self, request, instance):
|
|
circuits = Circuit.objects.restrict(request.user, 'view').filter(
|
|
Q(termination_a__provider_network=instance.pk) |
|
|
Q(termination_z__provider_network=instance.pk)
|
|
).prefetch_related(
|
|
'type', 'tenant', 'tenant__group', 'terminations__site'
|
|
)
|
|
circuits_table = tables.CircuitTable(circuits, user=request.user)
|
|
circuits_table.configure(request)
|
|
|
|
return {
|
|
'circuits_table': circuits_table,
|
|
}
|
|
|
|
|
|
class ProviderNetworkEditView(generic.ObjectEditView):
|
|
queryset = ProviderNetwork.objects.all()
|
|
form = forms.ProviderNetworkForm
|
|
|
|
|
|
class ProviderNetworkDeleteView(generic.ObjectDeleteView):
|
|
queryset = ProviderNetwork.objects.all()
|
|
|
|
|
|
class ProviderNetworkBulkImportView(generic.BulkImportView):
|
|
queryset = ProviderNetwork.objects.all()
|
|
model_form = forms.ProviderNetworkCSVForm
|
|
table = tables.ProviderNetworkTable
|
|
|
|
|
|
class ProviderNetworkBulkEditView(generic.BulkEditView):
|
|
queryset = ProviderNetwork.objects.all()
|
|
filterset = filtersets.ProviderNetworkFilterSet
|
|
table = tables.ProviderNetworkTable
|
|
form = forms.ProviderNetworkBulkEditForm
|
|
|
|
|
|
class ProviderNetworkBulkDeleteView(generic.BulkDeleteView):
|
|
queryset = ProviderNetwork.objects.all()
|
|
filterset = filtersets.ProviderNetworkFilterSet
|
|
table = tables.ProviderNetworkTable
|
|
|
|
|
|
#
|
|
# Circuit Types
|
|
#
|
|
|
|
class CircuitTypeListView(generic.ObjectListView):
|
|
queryset = CircuitType.objects.annotate(
|
|
circuit_count=count_related(Circuit, 'type')
|
|
)
|
|
filterset = filtersets.CircuitTypeFilterSet
|
|
filterset_form = forms.CircuitTypeFilterForm
|
|
table = tables.CircuitTypeTable
|
|
|
|
|
|
class CircuitTypeView(generic.ObjectView):
|
|
queryset = CircuitType.objects.all()
|
|
|
|
def get_extra_context(self, request, instance):
|
|
circuits = Circuit.objects.restrict(request.user, 'view').filter(type=instance)
|
|
circuits_table = tables.CircuitTable(circuits, user=request.user, exclude=('type',))
|
|
circuits_table.configure(request)
|
|
|
|
return {
|
|
'circuits_table': circuits_table,
|
|
}
|
|
|
|
|
|
class CircuitTypeEditView(generic.ObjectEditView):
|
|
queryset = CircuitType.objects.all()
|
|
form = forms.CircuitTypeForm
|
|
|
|
|
|
class CircuitTypeDeleteView(generic.ObjectDeleteView):
|
|
queryset = CircuitType.objects.all()
|
|
|
|
|
|
class CircuitTypeBulkImportView(generic.BulkImportView):
|
|
queryset = CircuitType.objects.all()
|
|
model_form = forms.CircuitTypeCSVForm
|
|
table = tables.CircuitTypeTable
|
|
|
|
|
|
class CircuitTypeBulkEditView(generic.BulkEditView):
|
|
queryset = CircuitType.objects.annotate(
|
|
circuit_count=count_related(Circuit, 'type')
|
|
)
|
|
filterset = filtersets.CircuitTypeFilterSet
|
|
table = tables.CircuitTypeTable
|
|
form = forms.CircuitTypeBulkEditForm
|
|
|
|
|
|
class CircuitTypeBulkDeleteView(generic.BulkDeleteView):
|
|
queryset = CircuitType.objects.annotate(
|
|
circuit_count=count_related(Circuit, 'type')
|
|
)
|
|
table = tables.CircuitTypeTable
|
|
|
|
|
|
#
|
|
# Circuits
|
|
#
|
|
|
|
class CircuitListView(generic.ObjectListView):
|
|
queryset = Circuit.objects.prefetch_related(
|
|
'provider', 'type', 'tenant', 'tenant__group', 'termination_a', 'termination_z'
|
|
)
|
|
filterset = filtersets.CircuitFilterSet
|
|
filterset_form = forms.CircuitFilterForm
|
|
table = tables.CircuitTable
|
|
|
|
|
|
class CircuitView(generic.ObjectView):
|
|
queryset = Circuit.objects.all()
|
|
|
|
|
|
class CircuitEditView(generic.ObjectEditView):
|
|
queryset = Circuit.objects.all()
|
|
form = forms.CircuitForm
|
|
|
|
|
|
class CircuitDeleteView(generic.ObjectDeleteView):
|
|
queryset = Circuit.objects.all()
|
|
|
|
|
|
class CircuitBulkImportView(generic.BulkImportView):
|
|
queryset = Circuit.objects.all()
|
|
model_form = forms.CircuitCSVForm
|
|
table = tables.CircuitTable
|
|
|
|
|
|
class CircuitBulkEditView(generic.BulkEditView):
|
|
queryset = Circuit.objects.prefetch_related(
|
|
'provider', 'type', 'tenant', 'terminations'
|
|
)
|
|
filterset = filtersets.CircuitFilterSet
|
|
table = tables.CircuitTable
|
|
form = forms.CircuitBulkEditForm
|
|
|
|
|
|
class CircuitBulkDeleteView(generic.BulkDeleteView):
|
|
queryset = Circuit.objects.prefetch_related(
|
|
'provider', 'type', 'tenant', 'terminations'
|
|
)
|
|
filterset = filtersets.CircuitFilterSet
|
|
table = tables.CircuitTable
|
|
|
|
|
|
class CircuitSwapTerminations(generic.ObjectEditView):
|
|
"""
|
|
Swap the A and Z terminations of a circuit.
|
|
"""
|
|
queryset = Circuit.objects.all()
|
|
|
|
def get(self, request, pk):
|
|
circuit = get_object_or_404(self.queryset, pk=pk)
|
|
form = ConfirmationForm()
|
|
|
|
# Circuit must have at least one termination to swap
|
|
if not circuit.termination_a and not circuit.termination_z:
|
|
messages.error(request, "No terminations have been defined for circuit {}.".format(circuit))
|
|
return redirect('circuits:circuit', pk=circuit.pk)
|
|
|
|
return render(request, 'circuits/circuit_terminations_swap.html', {
|
|
'circuit': circuit,
|
|
'termination_a': circuit.termination_a,
|
|
'termination_z': circuit.termination_z,
|
|
'form': form,
|
|
'panel_class': 'light',
|
|
'button_class': 'primary',
|
|
'return_url': circuit.get_absolute_url(),
|
|
})
|
|
|
|
def post(self, request, pk):
|
|
circuit = get_object_or_404(self.queryset, pk=pk)
|
|
form = ConfirmationForm(request.POST)
|
|
|
|
if form.is_valid():
|
|
|
|
termination_a = CircuitTermination.objects.filter(pk=circuit.termination_a_id).first()
|
|
termination_z = CircuitTermination.objects.filter(pk=circuit.termination_z_id).first()
|
|
|
|
if termination_a and termination_z:
|
|
# Use a placeholder to avoid an IntegrityError on the (circuit, term_side) unique constraint
|
|
with transaction.atomic():
|
|
termination_a.term_side = '_'
|
|
termination_a.save()
|
|
termination_z.term_side = 'A'
|
|
termination_z.save()
|
|
termination_a.term_side = 'Z'
|
|
termination_a.save()
|
|
circuit.refresh_from_db()
|
|
circuit.termination_a = termination_z
|
|
circuit.termination_z = termination_a
|
|
circuit.save()
|
|
elif termination_a:
|
|
termination_a.term_side = 'Z'
|
|
termination_a.save()
|
|
circuit.refresh_from_db()
|
|
circuit.termination_a = None
|
|
circuit.save()
|
|
else:
|
|
termination_z.term_side = 'A'
|
|
termination_z.save()
|
|
circuit.refresh_from_db()
|
|
circuit.termination_z = None
|
|
circuit.save()
|
|
|
|
messages.success(request, f"Swapped terminations for circuit {circuit}.")
|
|
return redirect('circuits:circuit', pk=circuit.pk)
|
|
|
|
return render(request, 'circuits/circuit_terminations_swap.html', {
|
|
'circuit': circuit,
|
|
'termination_a': circuit.termination_a,
|
|
'termination_z': circuit.termination_z,
|
|
'form': form,
|
|
'panel_class': 'default',
|
|
'button_class': 'primary',
|
|
'return_url': circuit.get_absolute_url(),
|
|
})
|
|
|
|
|
|
#
|
|
# Circuit terminations
|
|
#
|
|
|
|
class CircuitTerminationEditView(generic.ObjectEditView):
|
|
queryset = CircuitTermination.objects.all()
|
|
form = forms.CircuitTerminationForm
|
|
template_name = 'circuits/circuittermination_edit.html'
|
|
|
|
|
|
class CircuitTerminationDeleteView(generic.ObjectDeleteView):
|
|
queryset = CircuitTermination.objects.all()
|