From eb3d3dcbc4b65c819a0cb92de4794491f59f7687 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 18 Aug 2022 13:58:40 -0700 Subject: [PATCH 1/5] #6454 add prerequisite alert --- netbox/dcim/models/racks.py | 5 +++++ netbox/dcim/views.py | 1 + netbox/netbox/models/__init__.py | 4 ++++ netbox/netbox/views/generic/bulk_views.py | 15 +++++++++++++++ netbox/netbox/views/generic/object_views.py | 12 ++++++++++-- netbox/netbox/views/generic/utils.py | 12 ++++++++++++ netbox/templates/generic/object_edit.html | 4 ++++ netbox/templates/generic/object_list.html | 6 ++++++ netbox/templates/inc/missing_prerequisites.html | 5 +++++ 9 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 netbox/netbox/views/generic/utils.py create mode 100644 netbox/templates/inc/missing_prerequisites.html diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py index 81d699b11..e57934353 100644 --- a/netbox/dcim/models/racks.py +++ b/netbox/dcim/models/racks.py @@ -1,5 +1,6 @@ from collections import OrderedDict +from django.apps import apps from django.contrib.auth.models import User from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.models import ContentType @@ -202,6 +203,10 @@ class Rack(NetBoxModel): return f'{self.name} ({self.facility_id})' return self.name + @classmethod + def get_prerequisite_models(cls): + return [apps.get_model('dcim.Site'), ] + def get_absolute_url(self): return reverse('dcim:rack', args=[self.pk]) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 966d90876..6e77d4396 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -560,6 +560,7 @@ class RackRoleBulkDeleteView(generic.BulkDeleteView): # class RackListView(generic.ObjectListView): + required_prerequisites = [Site] queryset = Rack.objects.prefetch_related('devices__device_type').annotate( device_count=count_related(Device, 'rack') ) diff --git a/netbox/netbox/models/__init__.py b/netbox/netbox/models/__init__.py index ea2feb8de..2524c7c9b 100644 --- a/netbox/netbox/models/__init__.py +++ b/netbox/netbox/models/__init__.py @@ -52,6 +52,10 @@ class NetBoxModel(NetBoxFeatureSet, models.Model): class Meta: abstract = True + @classmethod + def get_prerequisite_models(cls): + return [] + class NestedGroupModel(NetBoxFeatureSet, MPTTModel): """ diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 5aea9c469..29007985c 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -25,6 +25,7 @@ from utilities.htmx import is_htmx from utilities.permissions import get_permission_for_model from utilities.views import GetReturnURLMixin from .base import BaseMultiObjectView +from .utils import get_prerequisite_model __all__ = ( 'BulkComponentCreateView', @@ -143,6 +144,7 @@ class ObjectListView(BaseMultiObjectView): """ model = self.queryset.model content_type = ContentType.objects.get_for_model(model) + requirement = get_prerequisite_model(self.queryset) if self.filterset: self.queryset = self.filterset(request.GET, self.queryset).qs @@ -198,6 +200,8 @@ class ObjectListView(BaseMultiObjectView): 'filter_form': self.filterset_form(request.GET, label_suffix='') if self.filterset_form else None, **self.get_extra_context(request), } + if requirement: + context['required_model'] = requirement return render(request, self.template_name, context) @@ -256,6 +260,17 @@ class BulkCreateView(GetReturnURLMixin, BaseMultiObjectView): form = self.form() model_form = self.model_form(initial=initial) + context = { + 'obj_type': self.model_form._meta.model._meta.verbose_name, + 'form': form, + 'model_form': model_form, + 'return_url': self.get_return_url(request), + **self.get_extra_context(request), + } + + if requirement: + context['required_model'] = requirement + return render(request, self.template_name, { 'obj_type': self.model_form._meta.model._meta.verbose_name, 'form': form, diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py index 88e078ae3..878f293a0 100644 --- a/netbox/netbox/views/generic/object_views.py +++ b/netbox/netbox/views/generic/object_views.py @@ -20,6 +20,7 @@ from utilities.permissions import get_permission_for_model from utilities.utils import get_viewname, normalize_querydict, prepare_cloned_fields from utilities.views import GetReturnURLMixin from .base import BaseObjectView +from .utils import get_prerequisite_model __all__ = ( 'ComponentCreateView', @@ -342,12 +343,19 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): form = self.form(instance=obj, initial=initial_data) restrict_form_fields(form, request.user) - return render(request, self.template_name, { + context = { 'object': obj, 'form': form, 'return_url': self.get_return_url(request, obj), **self.get_extra_context(request, obj), - }) + } + + requirement = get_prerequisite_model(self.queryset) + if requirement: + context['required_model'] = requirement + context['model'] = self.queryset.model + + return render(request, self.template_name, context) def post(self, request, *args, **kwargs): """ diff --git a/netbox/netbox/views/generic/utils.py b/netbox/netbox/views/generic/utils.py new file mode 100644 index 000000000..57c7b5eba --- /dev/null +++ b/netbox/netbox/views/generic/utils.py @@ -0,0 +1,12 @@ +def get_prerequisite_model(queryset): + requirement = None + model = queryset.model + + if not queryset.count(): + prerequisites = model.get_prerequisite_models() + if prerequisites: + for prereq in prerequisites: + if not prereq.objects.count(): + requirement = prereq + + return requirement diff --git a/netbox/templates/generic/object_edit.html b/netbox/templates/generic/object_edit.html index 892c7d2b1..73e9727bb 100644 --- a/netbox/templates/generic/object_edit.html +++ b/netbox/templates/generic/object_edit.html @@ -40,6 +40,10 @@ Context: {% endif %} + {% if required_model %} + {% include 'inc/missing_prerequisites.html' %} + {% endif %} +
{% csrf_token %} diff --git a/netbox/templates/generic/object_list.html b/netbox/templates/generic/object_list.html index 1e2ae796f..6910aa116 100644 --- a/netbox/templates/generic/object_list.html +++ b/netbox/templates/generic/object_list.html @@ -100,6 +100,12 @@ Context: {# Object table #} + + {% if required_model %} + {% include 'inc/missing_prerequisites.html' %} + {% endif %} + +
{% include 'htmx/table.html' %} diff --git a/netbox/templates/inc/missing_prerequisites.html b/netbox/templates/inc/missing_prerequisites.html new file mode 100644 index 000000000..c12b157d0 --- /dev/null +++ b/netbox/templates/inc/missing_prerequisites.html @@ -0,0 +1,5 @@ +{% load buttons %} + + From 928dff6b6879bf56c8953e0b137bbdaaa0a065e8 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 18 Aug 2022 15:11:03 -0700 Subject: [PATCH 2/5] #6454 add prerequisite alert --- netbox/circuits/models/circuits.py | 5 +++++ netbox/dcim/models/devices.py | 14 ++++++++++++++ netbox/dcim/models/power.py | 9 +++++++++ netbox/dcim/models/racks.py | 4 ++++ netbox/dcim/models/sites.py | 4 ++++ netbox/ipam/models/ip.py | 8 ++++++++ netbox/netbox/models/__init__.py | 8 ++++++++ netbox/netbox/views/generic/utils.py | 14 +++++++------- netbox/templates/inc/missing_prerequisites.html | 3 ++- netbox/virtualization/models.py | 8 ++++++++ netbox/wireless/models.py | 5 +++++ 11 files changed, 74 insertions(+), 8 deletions(-) diff --git a/netbox/circuits/models/circuits.py b/netbox/circuits/models/circuits.py index 02ba5209d..c14e365e1 100644 --- a/netbox/circuits/models/circuits.py +++ b/netbox/circuits/models/circuits.py @@ -1,3 +1,4 @@ +from django.apps import apps from django.contrib.contenttypes.fields import GenericRelation from django.core.exceptions import ValidationError from django.db import models @@ -129,6 +130,10 @@ class Circuit(NetBoxModel): def __str__(self): return self.cid + @classmethod + def get_prerequisite_models(cls): + return [apps.get_model('circuits.Provider'), CircuitType] + def get_absolute_url(self): return reverse('circuits:circuit', args=[self.pk]) diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index 91227f1cf..8d524dcb1 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -1,4 +1,6 @@ import yaml + +from django.apps import apps from django.contrib.contenttypes.fields import GenericRelation from django.core.exceptions import ValidationError from django.core.validators import MaxValueValidator, MinValueValidator @@ -155,6 +157,10 @@ class DeviceType(NetBoxModel): self._original_front_image = self.front_image self._original_rear_image = self.rear_image + @classmethod + def get_prerequisite_models(cls): + return [Manufacturer, ] + def get_absolute_url(self): return reverse('dcim:devicetype', args=[self.pk]) @@ -328,6 +334,10 @@ class ModuleType(NetBoxModel): def __str__(self): return self.model + @classmethod + def get_prerequisite_models(cls): + return [Manufacturer, ] + def get_absolute_url(self): return reverse('dcim:moduletype', args=[self.pk]) @@ -645,6 +655,10 @@ class Device(NetBoxModel, ConfigContextModel): return f'{self.device_type.manufacturer} {self.device_type.model} ({self.pk})' return super().__str__() + @classmethod + def get_prerequisite_models(cls): + return [apps.get_model('dcim.Site'), DeviceRole, DeviceType, ] + def get_absolute_url(self): return reverse('dcim:device', args=[self.pk]) diff --git a/netbox/dcim/models/power.py b/netbox/dcim/models/power.py index 5978d86bd..5e355ce42 100644 --- a/netbox/dcim/models/power.py +++ b/netbox/dcim/models/power.py @@ -1,3 +1,4 @@ +from django.apps import apps from django.contrib.contenttypes.fields import GenericRelation from django.core.exceptions import ValidationError from django.core.validators import MaxValueValidator, MinValueValidator @@ -54,6 +55,10 @@ class PowerPanel(NetBoxModel): def __str__(self): return self.name + @classmethod + def get_prerequisite_models(cls): + return [apps.get_model('dcim.Site'), ] + def get_absolute_url(self): return reverse('dcim:powerpanel', args=[self.pk]) @@ -138,6 +143,10 @@ class PowerFeed(NetBoxModel, PathEndpoint, LinkTermination): def __str__(self): return self.name + @classmethod + def get_prerequisite_models(cls): + return [PowerPanel, ] + def get_absolute_url(self): return reverse('dcim:powerfeed', args=[self.pk]) diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py index e57934353..d0600e987 100644 --- a/netbox/dcim/models/racks.py +++ b/netbox/dcim/models/racks.py @@ -473,6 +473,10 @@ class RackReservation(NetBoxModel): def __str__(self): return "Reservation for rack {}".format(self.rack) + @classmethod + def get_prerequisite_models(cls): + return [apps.get_model('dcim.Site'), Rack, ] + def get_absolute_url(self): return reverse('dcim:rackreservation', args=[self.pk]) diff --git a/netbox/dcim/models/sites.py b/netbox/dcim/models/sites.py index d02bd0932..70b4e6421 100644 --- a/netbox/dcim/models/sites.py +++ b/netbox/dcim/models/sites.py @@ -406,6 +406,10 @@ class Location(NestedGroupModel): super().validate_unique(exclude=exclude) + @classmethod + def get_prerequisite_models(cls): + return [Site, ] + def get_absolute_url(self): return reverse('dcim:location', args=[self.pk]) diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py index d1538953a..ec054339c 100644 --- a/netbox/ipam/models/ip.py +++ b/netbox/ipam/models/ip.py @@ -124,6 +124,10 @@ class ASN(NetBoxModel): def __str__(self): return f'AS{self.asn_with_asdot}' + @classmethod + def get_prerequisite_models(cls): + return [RIR, ] + def get_absolute_url(self): return reverse('ipam:asn', args=[self.pk]) @@ -185,6 +189,10 @@ class Aggregate(GetAvailablePrefixesMixin, NetBoxModel): def __str__(self): return str(self.prefix) + @classmethod + def get_prerequisite_models(cls): + return [RIR, ] + def get_absolute_url(self): return reverse('ipam:aggregate', args=[self.pk]) diff --git a/netbox/netbox/models/__init__.py b/netbox/netbox/models/__init__.py index 2524c7c9b..675103d06 100644 --- a/netbox/netbox/models/__init__.py +++ b/netbox/netbox/models/__init__.py @@ -89,6 +89,10 @@ class NestedGroupModel(NetBoxFeatureSet, MPTTModel): def __str__(self): return self.name + @classmethod + def get_prerequisite_models(cls): + return [] + def clean(self): super().clean() @@ -126,3 +130,7 @@ class OrganizationalModel(NetBoxFeatureSet, models.Model): class Meta: abstract = True ordering = ('name',) + + @classmethod + def get_prerequisite_models(cls): + return [] diff --git a/netbox/netbox/views/generic/utils.py b/netbox/netbox/views/generic/utils.py index 57c7b5eba..c682181a1 100644 --- a/netbox/netbox/views/generic/utils.py +++ b/netbox/netbox/views/generic/utils.py @@ -1,12 +1,12 @@ def get_prerequisite_model(queryset): - requirement = None model = queryset.model if not queryset.count(): - prerequisites = model.get_prerequisite_models() - if prerequisites: - for prereq in prerequisites: - if not prereq.objects.count(): - requirement = prereq + if hasattr(model, 'get_prerequisite_models'): + prerequisites = model.get_prerequisite_models() + if prerequisites: + for prereq in prerequisites: + if not prereq.objects.count(): + return prereq - return requirement + return None diff --git a/netbox/templates/inc/missing_prerequisites.html b/netbox/templates/inc/missing_prerequisites.html index c12b157d0..04043fc9c 100644 --- a/netbox/templates/inc/missing_prerequisites.html +++ b/netbox/templates/inc/missing_prerequisites.html @@ -1,5 +1,6 @@ {% load buttons %} diff --git a/netbox/virtualization/models.py b/netbox/virtualization/models.py index 586bb8a9e..b7151a1f0 100644 --- a/netbox/virtualization/models.py +++ b/netbox/virtualization/models.py @@ -162,6 +162,10 @@ class Cluster(NetBoxModel): def __str__(self): return self.name + @classmethod + def get_prerequisite_models(cls): + return [ClusterType, ] + def get_absolute_url(self): return reverse('virtualization:cluster', args=[self.pk]) @@ -288,6 +292,10 @@ class VirtualMachine(NetBoxModel, ConfigContextModel): def __str__(self): return self.name + @classmethod + def get_prerequisite_models(cls): + return [Cluster, ] + def get_absolute_url(self): return reverse('virtualization:virtualmachine', args=[self.pk]) diff --git a/netbox/wireless/models.py b/netbox/wireless/models.py index 0543e5621..f9838c0c7 100644 --- a/netbox/wireless/models.py +++ b/netbox/wireless/models.py @@ -1,3 +1,4 @@ +from django.apps import apps from django.core.exceptions import ValidationError from django.db import models from django.urls import reverse @@ -174,6 +175,10 @@ class WirelessLink(WirelessAuthenticationBase, NetBoxModel): def __str__(self): return f'#{self.pk}' + @classmethod + def get_prerequisite_models(cls): + return [apps.get_model('dcim.Interface'), ] + def get_absolute_url(self): return reverse('wireless:wirelesslink', args=[self.pk]) From c65a29169878ef44e131a7601578781c595c8cf3 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 18 Aug 2022 16:00:17 -0700 Subject: [PATCH 3/5] #6454 add L2VPN check --- netbox/ipam/models/l2vpn.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/netbox/ipam/models/l2vpn.py b/netbox/ipam/models/l2vpn.py index 0e948b18e..809007033 100644 --- a/netbox/ipam/models/l2vpn.py +++ b/netbox/ipam/models/l2vpn.py @@ -1,3 +1,4 @@ +from django.apps import apps from django.contrib.contenttypes.fields import GenericRelation, GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError @@ -103,6 +104,10 @@ class L2VPNTermination(NetBoxModel): return f'{self.assigned_object} <> {self.l2vpn}' return super().__str__() + @classmethod + def get_prerequisite_models(cls): + return [apps.get_model('ipam.L2VPN'), ] + def get_absolute_url(self): return reverse('ipam:l2vpntermination', args=[self.pk]) From a972174706c2b4e857ca7019b4524c7216520fac Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 22 Aug 2022 11:46:41 -0700 Subject: [PATCH 4/5] #6454 changes from PR review --- netbox/dcim/views.py | 1 - netbox/netbox/models/__init__.py | 20 ++++++++----------- netbox/netbox/views/generic/bulk_views.py | 15 +------------- netbox/netbox/views/generic/object_views.py | 15 ++++++-------- netbox/netbox/views/generic/utils.py | 4 ++-- netbox/templates/generic/object_edit.html | 2 +- netbox/templates/generic/object_list.html | 2 +- .../templates/inc/missing_prerequisites.html | 4 ++-- 8 files changed, 21 insertions(+), 42 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index c807176d4..a31eabc5e 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -570,7 +570,6 @@ class RackRoleBulkDeleteView(generic.BulkDeleteView): # class RackListView(generic.ObjectListView): - required_prerequisites = [Site] queryset = Rack.objects.annotate( device_count=count_related(Device, 'rack') ) diff --git a/netbox/netbox/models/__init__.py b/netbox/netbox/models/__init__.py index c36d36f46..4c65094ca 100644 --- a/netbox/netbox/models/__init__.py +++ b/netbox/netbox/models/__init__.py @@ -28,6 +28,14 @@ class NetBoxFeatureSet( class Meta: abstract = True + @classmethod + def get_prerequisite_models(cls): + """ + Return a list of model types that are required to create this model or empty list if none. This is used for + showing prequisite warnings in the UI on the list and detail views. + """ + return [] + # # Base model classes @@ -53,10 +61,6 @@ class NetBoxModel(NetBoxFeatureSet, models.Model): class Meta: abstract = True - @classmethod - def get_prerequisite_models(cls): - return [] - def clone(self): """ Return a dictionary of attributes suitable for creating a copy of the current instance. This is used for pre- @@ -109,10 +113,6 @@ class NestedGroupModel(NetBoxFeatureSet, MPTTModel): def __str__(self): return self.name - @classmethod - def get_prerequisite_models(cls): - return [] - def clean(self): super().clean() @@ -150,7 +150,3 @@ class OrganizationalModel(NetBoxFeatureSet, models.Model): class Meta: abstract = True ordering = ('name',) - - @classmethod - def get_prerequisite_models(cls): - return [] diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index d30d67468..8fe0ad518 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -172,12 +172,10 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin): 'table': table, 'actions': actions, 'filter_form': self.filterset_form(request.GET, label_suffix='') if self.filterset_form else None, + 'prerequisite_model': requirement if requirement else None, **self.get_extra_context(request), } - if requirement: - context['required_model'] = requirement - return render(request, self.template_name, context) @@ -235,17 +233,6 @@ class BulkCreateView(GetReturnURLMixin, BaseMultiObjectView): form = self.form() model_form = self.model_form(initial=initial) - context = { - 'obj_type': self.model_form._meta.model._meta.verbose_name, - 'form': form, - 'model_form': model_form, - 'return_url': self.get_return_url(request), - **self.get_extra_context(request), - } - - if requirement: - context['required_model'] = requirement - return render(request, self.template_name, { 'obj_type': self.model_form._meta.model._meta.verbose_name, 'form': form, diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py index 7c63b2ec6..c9ff738d7 100644 --- a/netbox/netbox/views/generic/object_views.py +++ b/netbox/netbox/views/generic/object_views.py @@ -341,24 +341,21 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): """ obj = self.get_object(**kwargs) obj = self.alter_object(obj, request, args, kwargs) + model = self.queryset.model initial_data = normalize_querydict(request.GET) form = self.form(instance=obj, initial=initial_data) restrict_form_fields(form, request.user) - context = { + requirement = get_prerequisite_model(self.queryset) + return render(request, self.template_name, { + 'model': model, 'object': obj, 'form': form, 'return_url': self.get_return_url(request, obj), + 'prerequisite_model': requirement if requirement else None, **self.get_extra_context(request, obj), - } - - requirement = get_prerequisite_model(self.queryset) - if requirement: - context['required_model'] = requirement - context['model'] = self.queryset.model - - return render(request, self.template_name, context) + }) def post(self, request, *args, **kwargs): """ diff --git a/netbox/netbox/views/generic/utils.py b/netbox/netbox/views/generic/utils.py index c682181a1..61c6dc242 100644 --- a/netbox/netbox/views/generic/utils.py +++ b/netbox/netbox/views/generic/utils.py @@ -1,12 +1,12 @@ def get_prerequisite_model(queryset): model = queryset.model - if not queryset.count(): + if not queryset.exists(): if hasattr(model, 'get_prerequisite_models'): prerequisites = model.get_prerequisite_models() if prerequisites: for prereq in prerequisites: - if not prereq.objects.count(): + if not prereq.objects.exists(): return prereq return None diff --git a/netbox/templates/generic/object_edit.html b/netbox/templates/generic/object_edit.html index 73e9727bb..8047dc59d 100644 --- a/netbox/templates/generic/object_edit.html +++ b/netbox/templates/generic/object_edit.html @@ -40,7 +40,7 @@ Context:
{% endif %} - {% if required_model %} + {% if prerequisite_model %} {% include 'inc/missing_prerequisites.html' %} {% endif %} diff --git a/netbox/templates/generic/object_list.html b/netbox/templates/generic/object_list.html index 6910aa116..9d3952a28 100644 --- a/netbox/templates/generic/object_list.html +++ b/netbox/templates/generic/object_list.html @@ -101,7 +101,7 @@ Context: {# Object table #} - {% if required_model %} + {% if prerequisite_model %} {% include 'inc/missing_prerequisites.html' %} {% endif %} diff --git a/netbox/templates/inc/missing_prerequisites.html b/netbox/templates/inc/missing_prerequisites.html index 04043fc9c..5814b72eb 100644 --- a/netbox/templates/inc/missing_prerequisites.html +++ b/netbox/templates/inc/missing_prerequisites.html @@ -1,6 +1,6 @@ {% load buttons %} From 25ec624e4e97026088950e213bc5ec6dcd1d0bff Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 22 Aug 2022 12:59:26 -0700 Subject: [PATCH 5/5] #6454 suggested review changes --- netbox/netbox/views/generic/bulk_views.py | 3 +-- netbox/netbox/views/generic/object_views.py | 3 +-- netbox/templates/generic/object_list.html | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 8fe0ad518..7340ea2a0 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -124,7 +124,6 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin): """ model = self.queryset.model content_type = ContentType.objects.get_for_model(model) - requirement = get_prerequisite_model(self.queryset) if self.filterset: self.queryset = self.filterset(request.GET, self.queryset).qs @@ -172,7 +171,7 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin): 'table': table, 'actions': actions, 'filter_form': self.filterset_form(request.GET, label_suffix='') if self.filterset_form else None, - 'prerequisite_model': requirement if requirement else None, + 'prerequisite_model': get_prerequisite_model(self.queryset), **self.get_extra_context(request), } diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py index c9ff738d7..19401f79a 100644 --- a/netbox/netbox/views/generic/object_views.py +++ b/netbox/netbox/views/generic/object_views.py @@ -347,13 +347,12 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): form = self.form(instance=obj, initial=initial_data) restrict_form_fields(form, request.user) - requirement = get_prerequisite_model(self.queryset) return render(request, self.template_name, { 'model': model, 'object': obj, 'form': form, 'return_url': self.get_return_url(request, obj), - 'prerequisite_model': requirement if requirement else None, + 'prerequisite_model': get_prerequisite_model(self.queryset), **self.get_extra_context(request, obj), }) diff --git a/netbox/templates/generic/object_list.html b/netbox/templates/generic/object_list.html index 9d3952a28..60eba6097 100644 --- a/netbox/templates/generic/object_list.html +++ b/netbox/templates/generic/object_list.html @@ -105,7 +105,6 @@ Context: {% include 'inc/missing_prerequisites.html' %} {% endif %} -
{% include 'htmx/table.html' %}