mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
Fix some instances where RestrictedQuerySet is evaluated prematurely
This commit is contained in:
parent
9777f25b9f
commit
95965d65c9
@ -5,7 +5,7 @@ from django.contrib import messages
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.paginator import EmptyPage, PageNotAnInteger
|
from django.core.paginator import EmptyPage, PageNotAnInteger
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Count, F
|
from django.db.models import Count, F, Prefetch
|
||||||
from django.forms import ModelMultipleChoiceField, MultipleHiddenInput, modelformset_factory
|
from django.forms import ModelMultipleChoiceField, MultipleHiddenInput, modelformset_factory
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
@ -16,7 +16,7 @@ from django.views.generic import View
|
|||||||
from circuits.models import Circuit
|
from circuits.models import Circuit
|
||||||
from extras.models import Graph
|
from extras.models import Graph
|
||||||
from extras.views import ObjectConfigContextView
|
from extras.views import ObjectConfigContextView
|
||||||
from ipam.models import Prefix, Service, VLAN
|
from ipam.models import IPAddress, Prefix, Service, VLAN
|
||||||
from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
|
from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
|
||||||
from secrets.models import Secret
|
from secrets.models import Secret
|
||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
@ -517,6 +517,7 @@ class DeviceTypeView(ObjectView):
|
|||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
devicetype = get_object_or_404(self.queryset, pk=pk)
|
devicetype = get_object_or_404(self.queryset, pk=pk)
|
||||||
|
instance_count = Device.objects.restrict(request.user).filter(device_type=devicetype).count()
|
||||||
|
|
||||||
# Component tables
|
# Component tables
|
||||||
consoleport_table = tables.ConsolePortTemplateTable(
|
consoleport_table = tables.ConsolePortTemplateTable(
|
||||||
@ -563,6 +564,7 @@ class DeviceTypeView(ObjectView):
|
|||||||
|
|
||||||
return render(request, 'dcim/devicetype.html', {
|
return render(request, 'dcim/devicetype.html', {
|
||||||
'devicetype': devicetype,
|
'devicetype': devicetype,
|
||||||
|
'instance_count': instance_count,
|
||||||
'consoleport_table': consoleport_table,
|
'consoleport_table': consoleport_table,
|
||||||
'consoleserverport_table': consoleserverport_table,
|
'consoleserverport_table': consoleserverport_table,
|
||||||
'powerport_table': powerport_table,
|
'powerport_table': powerport_table,
|
||||||
@ -987,8 +989,10 @@ class DeviceView(ObjectView):
|
|||||||
|
|
||||||
# Interfaces
|
# Interfaces
|
||||||
interfaces = device.vc_interfaces.restrict(request.user, 'view').filter(device=device).prefetch_related(
|
interfaces = device.vc_interfaces.restrict(request.user, 'view').filter(device=device).prefetch_related(
|
||||||
|
Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user)),
|
||||||
|
Prefetch('member_interfaces', queryset=Interface.objects.restrict(request.user)),
|
||||||
'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable',
|
'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable',
|
||||||
'cable__termination_a', 'cable__termination_b', 'ip_addresses', 'tags'
|
'cable__termination_a', 'cable__termination_b', 'tags'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Front ports
|
# Front ports
|
||||||
@ -1438,7 +1442,7 @@ class InterfaceView(ObjectView):
|
|||||||
if interface.untagged_vlan is not None:
|
if interface.untagged_vlan is not None:
|
||||||
vlans.append(interface.untagged_vlan)
|
vlans.append(interface.untagged_vlan)
|
||||||
vlans[0].tagged = False
|
vlans[0].tagged = False
|
||||||
for vlan in interface.tagged_vlans.prefetch_related('site', 'group', 'tenant', 'role'):
|
for vlan in interface.tagged_vlans.restrict(request.user).prefetch_related('site', 'group', 'tenant', 'role'):
|
||||||
vlan.tagged = True
|
vlan.tagged = True
|
||||||
vlans.append(vlan)
|
vlans.append(vlan)
|
||||||
vlan_table = InterfaceVLANTable(
|
vlan_table = InterfaceVLANTable(
|
||||||
@ -2149,13 +2153,15 @@ class VirtualChassisListView(ObjectListView):
|
|||||||
|
|
||||||
|
|
||||||
class VirtualChassisView(ObjectView):
|
class VirtualChassisView(ObjectView):
|
||||||
queryset = VirtualChassis.objects.prefetch_related('members')
|
queryset = VirtualChassis.objects.all()
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
virtualchassis = get_object_or_404(self.queryset, pk=pk)
|
virtualchassis = get_object_or_404(self.queryset, pk=pk)
|
||||||
|
members = Device.objects.restrict(request.user).filter(virtual_chassis=virtualchassis)
|
||||||
|
|
||||||
return render(request, 'dcim/virtualchassis.html', {
|
return render(request, 'dcim/virtualchassis.html', {
|
||||||
'virtualchassis': virtualchassis,
|
'virtualchassis': virtualchassis,
|
||||||
|
'members': members,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -2389,8 +2395,9 @@ class PowerPanelView(ObjectView):
|
|||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
powerpanel = get_object_or_404(self.queryset, pk=pk)
|
powerpanel = get_object_or_404(self.queryset, pk=pk)
|
||||||
|
power_feeds = PowerFeed.objects.restrict(request.user).filter(power_panel=powerpanel).prefetch_related('rack')
|
||||||
powerfeed_table = tables.PowerFeedTable(
|
powerfeed_table = tables.PowerFeedTable(
|
||||||
data=PowerFeed.objects.filter(power_panel=powerpanel).prefetch_related('rack'),
|
data=power_feeds,
|
||||||
orderable=False
|
orderable=False
|
||||||
)
|
)
|
||||||
powerfeed_table.exclude = ['power_panel']
|
powerfeed_table.exclude = ['power_panel']
|
||||||
|
@ -2,13 +2,15 @@ from django import template
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db.models import Count, Q
|
from django.db.models import Count, Prefetch, Q
|
||||||
from django.http import Http404, HttpResponseForbidden
|
from django.http import Http404, HttpResponseForbidden
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from django_tables2 import RequestConfig
|
from django_tables2 import RequestConfig
|
||||||
|
|
||||||
|
from dcim.models import DeviceRole, Platform, Region, Site
|
||||||
|
from tenancy.models import Tenant, TenantGroup
|
||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
from utilities.paginator import EnhancedPaginator
|
from utilities.paginator import EnhancedPaginator
|
||||||
from utilities.utils import shallow_compare_dict
|
from utilities.utils import shallow_compare_dict
|
||||||
@ -16,6 +18,7 @@ from utilities.views import (
|
|||||||
BulkDeleteView, BulkEditView, BulkImportView, ObjectView, ObjectDeleteView, ObjectEditView, ObjectListView,
|
BulkDeleteView, BulkEditView, BulkImportView, ObjectView, ObjectDeleteView, ObjectEditView, ObjectListView,
|
||||||
ObjectPermissionRequiredMixin,
|
ObjectPermissionRequiredMixin,
|
||||||
)
|
)
|
||||||
|
from virtualization.models import Cluster, ClusterGroup
|
||||||
from . import filters, forms, tables
|
from . import filters, forms, tables
|
||||||
from .models import ConfigContext, ImageAttachment, ObjectChange, ReportResult, Tag, TaggedItem
|
from .models import ConfigContext, ImageAttachment, ObjectChange, ReportResult, Tag, TaggedItem
|
||||||
from .reports import get_report, get_reports
|
from .reports import get_report, get_reports
|
||||||
@ -120,6 +123,18 @@ class ConfigContextView(ObjectView):
|
|||||||
queryset = ConfigContext.objects.all()
|
queryset = ConfigContext.objects.all()
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
# Extend queryset to prefetch related objects
|
||||||
|
self.queryset = self.queryset.prefetch_related(
|
||||||
|
Prefetch('regions', queryset=Region.objects.restrict(request.user)),
|
||||||
|
Prefetch('sites', queryset=Site.objects.restrict(request.user)),
|
||||||
|
Prefetch('roles', queryset=DeviceRole.objects.restrict(request.user)),
|
||||||
|
Prefetch('platforms', queryset=Platform.objects.restrict(request.user)),
|
||||||
|
Prefetch('clusters', queryset=Cluster.objects.restrict(request.user)),
|
||||||
|
Prefetch('cluster_groups', queryset=ClusterGroup.objects.restrict(request.user)),
|
||||||
|
Prefetch('tenants', queryset=Tenant.objects.restrict(request.user)),
|
||||||
|
Prefetch('tenant_groups', queryset=TenantGroup.objects.restrict(request.user)),
|
||||||
|
)
|
||||||
|
|
||||||
configcontext = get_object_or_404(self.queryset, pk=pk)
|
configcontext = get_object_or_404(self.queryset, pk=pk)
|
||||||
|
|
||||||
# Determine user's preferred output format
|
# Determine user's preferred output format
|
||||||
|
@ -255,7 +255,7 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel):
|
|||||||
"""
|
"""
|
||||||
Determine the prefix utilization of the aggregate and return it as a percentage.
|
Determine the prefix utilization of the aggregate and return it as a percentage.
|
||||||
"""
|
"""
|
||||||
queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(self.prefix))
|
queryset = Prefix.objects.unrestricted().filter(prefix__net_contained_or_equal=str(self.prefix))
|
||||||
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
|
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
|
||||||
return int(float(child_prefixes.size) / self.prefix.size * 100)
|
return int(float(child_prefixes.size) / self.prefix.size * 100)
|
||||||
|
|
||||||
@ -553,7 +553,10 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
|
|||||||
"container", calculate utilization based on child prefixes. For all others, count child IP addresses.
|
"container", calculate utilization based on child prefixes. For all others, count child IP addresses.
|
||||||
"""
|
"""
|
||||||
if self.status == PrefixStatusChoices.STATUS_CONTAINER:
|
if self.status == PrefixStatusChoices.STATUS_CONTAINER:
|
||||||
queryset = Prefix.objects.filter(prefix__net_contained=str(self.prefix), vrf=self.vrf)
|
queryset = Prefix.objects.unrestricted().filter(
|
||||||
|
prefix__net_contained=str(self.prefix),
|
||||||
|
vrf=self.vrf
|
||||||
|
)
|
||||||
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
|
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
|
||||||
return int(float(child_prefixes.size) / self.prefix.size * 100)
|
return int(float(child_prefixes.size) / self.prefix.size * 100)
|
||||||
else:
|
else:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import netaddr
|
import netaddr
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Count
|
from django.db.models import Count, Prefetch
|
||||||
from django.db.models.expressions import RawSQL
|
from django.db.models.expressions import RawSQL
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django_tables2 import RequestConfig
|
from django_tables2 import RequestConfig
|
||||||
@ -108,10 +108,12 @@ class RIRListView(ObjectListView):
|
|||||||
'deprecated': 0,
|
'deprecated': 0,
|
||||||
'available': 0,
|
'available': 0,
|
||||||
}
|
}
|
||||||
aggregate_list = Aggregate.objects.filter(prefix__family=family, rir=rir)
|
aggregate_list = Aggregate.objects.restrict(request.user).filter(prefix__family=family, rir=rir)
|
||||||
for aggregate in aggregate_list:
|
for aggregate in aggregate_list:
|
||||||
|
|
||||||
queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(aggregate.prefix))
|
queryset = Prefix.objects.restrict(request.user).filter(
|
||||||
|
prefix__net_contained_or_equal=str(aggregate.prefix)
|
||||||
|
)
|
||||||
|
|
||||||
# Find all consumed space for each prefix status (we ignore containers for this purpose).
|
# Find all consumed space for each prefix status (we ignore containers for this purpose).
|
||||||
active_prefixes = netaddr.cidr_merge(
|
active_prefixes = netaddr.cidr_merge(
|
||||||
@ -699,7 +701,9 @@ class VLANGroupVLANsView(ObjectView):
|
|||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
vlan_group = get_object_or_404(self.queryset, pk=pk)
|
vlan_group = get_object_or_404(self.queryset, pk=pk)
|
||||||
|
|
||||||
vlans = VLAN.objects.restrict(request.user, 'view').filter(group_id=pk)
|
vlans = VLAN.objects.restrict(request.user, 'view').filter(group_id=pk).prefetch_related(
|
||||||
|
Prefetch('prefixes', queryset=Prefix.objects.restrict(request.user))
|
||||||
|
)
|
||||||
vlans = add_available_vlans(vlan_group, vlans)
|
vlans = add_available_vlans(vlan_group, vlans)
|
||||||
|
|
||||||
vlan_table = tables.VLANDetailTable(vlans)
|
vlan_table = tables.VLANDetailTable(vlans)
|
||||||
|
@ -131,7 +131,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Instances</td>
|
<td>Instances</td>
|
||||||
<td><a href="{% url 'dcim:device_list' %}?device_type_id={{ devicetype.pk }}">{{ devicetype.instances.count }}</a></td>
|
<td><a href="{% url 'dcim:device_list' %}?device_type_id={{ devicetype.pk }}">{{ instance_count }}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
<th>Master</th>
|
<th>Master</th>
|
||||||
<th>Priority</th>
|
<th>Priority</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for vc_member in virtualchassis.members.all %}
|
{% for vc_member in members %}
|
||||||
<tr{% if vc_member == device %} class="info"{% endif %}>
|
<tr{% if vc_member == device %} class="info"{% endif %}>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ vc_member.get_absolute_url }}">{{ vc_member }}</a>
|
<a href="{{ vc_member.get_absolute_url }}">{{ vc_member }}</a>
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Count
|
from django.db.models import Count, Prefetch
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from dcim.models import Device
|
from dcim.models import Device
|
||||||
from dcim.tables import DeviceTable
|
from dcim.tables import DeviceTable
|
||||||
from extras.views import ObjectConfigContextView
|
from extras.views import ObjectConfigContextView
|
||||||
from ipam.models import Service
|
from ipam.models import IPAddress, Service
|
||||||
from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
|
from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
|
||||||
from utilities.views import (
|
from utilities.views import (
|
||||||
BulkComponentCreateView, BulkDeleteView, BulkEditView, BulkImportView, BulkRenameView, ComponentCreateView,
|
BulkComponentCreateView, BulkDeleteView, BulkEditView, BulkImportView, BulkRenameView, ComponentCreateView,
|
||||||
@ -88,6 +88,9 @@ class ClusterView(ObjectView):
|
|||||||
queryset = Cluster.objects.all()
|
queryset = Cluster.objects.all()
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
self.queryset = self.queryset.prefetch_related(
|
||||||
|
Prefetch('virtual_machines', queryset=VirtualMachine.objects.restrict(request.user))
|
||||||
|
)
|
||||||
|
|
||||||
cluster = get_object_or_404(self.queryset, pk=pk)
|
cluster = get_object_or_404(self.queryset, pk=pk)
|
||||||
devices = Device.objects.restrict(request.user, 'view').filter(cluster=cluster).prefetch_related(
|
devices = Device.objects.restrict(request.user, 'view').filter(cluster=cluster).prefetch_related(
|
||||||
@ -236,8 +239,16 @@ class VirtualMachineView(ObjectView):
|
|||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
virtualmachine = get_object_or_404(self.queryset, pk=pk)
|
virtualmachine = get_object_or_404(self.queryset, pk=pk)
|
||||||
interfaces = VMInterface.objects.restrict(request.user, 'view').filter(virtual_machine=virtualmachine)
|
interfaces = VMInterface.objects.restrict(request.user, 'view').filter(
|
||||||
services = Service.objects.restrict(request.user, 'view').filter(virtual_machine=virtualmachine)
|
virtual_machine=virtualmachine
|
||||||
|
).prefetch_related(
|
||||||
|
Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user))
|
||||||
|
)
|
||||||
|
services = Service.objects.restrict(request.user, 'view').filter(
|
||||||
|
virtual_machine=virtualmachine
|
||||||
|
).prefetch_related(
|
||||||
|
Prefetch('ipaddresses', queryset=IPAddress.objects.restrict(request.user))
|
||||||
|
)
|
||||||
|
|
||||||
return render(request, 'virtualization/virtualmachine.html', {
|
return render(request, 'virtualization/virtualmachine.html', {
|
||||||
'virtualmachine': virtualmachine,
|
'virtualmachine': virtualmachine,
|
||||||
@ -315,7 +326,7 @@ class VMInterfaceView(ObjectView):
|
|||||||
if vminterface.untagged_vlan is not None:
|
if vminterface.untagged_vlan is not None:
|
||||||
vlans.append(vminterface.untagged_vlan)
|
vlans.append(vminterface.untagged_vlan)
|
||||||
vlans[0].tagged = False
|
vlans[0].tagged = False
|
||||||
for vlan in vminterface.tagged_vlans.prefetch_related('site', 'group', 'tenant', 'role'):
|
for vlan in vminterface.tagged_vlans.restrict(request.user).prefetch_related('site', 'group', 'tenant', 'role'):
|
||||||
vlan.tagged = True
|
vlan.tagged = True
|
||||||
vlans.append(vlan)
|
vlans.append(vlan)
|
||||||
vlan_table = InterfaceVLANTable(
|
vlan_table = InterfaceVLANTable(
|
||||||
|
Loading…
Reference in New Issue
Block a user