mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-16 04:02:52 -06:00
#6454 add prerequisite alert
This commit is contained in:
parent
7a44a4e305
commit
eb3d3dcbc4
@ -1,5 +1,6 @@
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
from django.apps import apps
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.contenttypes.fields import GenericRelation
|
from django.contrib.contenttypes.fields import GenericRelation
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
@ -202,6 +203,10 @@ class Rack(NetBoxModel):
|
|||||||
return f'{self.name} ({self.facility_id})'
|
return f'{self.name} ({self.facility_id})'
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_prerequisite_models(cls):
|
||||||
|
return [apps.get_model('dcim.Site'), ]
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('dcim:rack', args=[self.pk])
|
return reverse('dcim:rack', args=[self.pk])
|
||||||
|
|
||||||
|
@ -560,6 +560,7 @@ class RackRoleBulkDeleteView(generic.BulkDeleteView):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class RackListView(generic.ObjectListView):
|
class RackListView(generic.ObjectListView):
|
||||||
|
required_prerequisites = [Site]
|
||||||
queryset = Rack.objects.prefetch_related('devices__device_type').annotate(
|
queryset = Rack.objects.prefetch_related('devices__device_type').annotate(
|
||||||
device_count=count_related(Device, 'rack')
|
device_count=count_related(Device, 'rack')
|
||||||
)
|
)
|
||||||
|
@ -52,6 +52,10 @@ class NetBoxModel(NetBoxFeatureSet, models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_prerequisite_models(cls):
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
class NestedGroupModel(NetBoxFeatureSet, MPTTModel):
|
class NestedGroupModel(NetBoxFeatureSet, MPTTModel):
|
||||||
"""
|
"""
|
||||||
|
@ -25,6 +25,7 @@ from utilities.htmx import is_htmx
|
|||||||
from utilities.permissions import get_permission_for_model
|
from utilities.permissions import get_permission_for_model
|
||||||
from utilities.views import GetReturnURLMixin
|
from utilities.views import GetReturnURLMixin
|
||||||
from .base import BaseMultiObjectView
|
from .base import BaseMultiObjectView
|
||||||
|
from .utils import get_prerequisite_model
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'BulkComponentCreateView',
|
'BulkComponentCreateView',
|
||||||
@ -143,6 +144,7 @@ class ObjectListView(BaseMultiObjectView):
|
|||||||
"""
|
"""
|
||||||
model = self.queryset.model
|
model = self.queryset.model
|
||||||
content_type = ContentType.objects.get_for_model(model)
|
content_type = ContentType.objects.get_for_model(model)
|
||||||
|
requirement = get_prerequisite_model(self.queryset)
|
||||||
|
|
||||||
if self.filterset:
|
if self.filterset:
|
||||||
self.queryset = self.filterset(request.GET, self.queryset).qs
|
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,
|
'filter_form': self.filterset_form(request.GET, label_suffix='') if self.filterset_form else None,
|
||||||
**self.get_extra_context(request),
|
**self.get_extra_context(request),
|
||||||
}
|
}
|
||||||
|
if requirement:
|
||||||
|
context['required_model'] = requirement
|
||||||
|
|
||||||
return render(request, self.template_name, context)
|
return render(request, self.template_name, context)
|
||||||
|
|
||||||
@ -256,6 +260,17 @@ class BulkCreateView(GetReturnURLMixin, BaseMultiObjectView):
|
|||||||
form = self.form()
|
form = self.form()
|
||||||
model_form = self.model_form(initial=initial)
|
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, {
|
return render(request, self.template_name, {
|
||||||
'obj_type': self.model_form._meta.model._meta.verbose_name,
|
'obj_type': self.model_form._meta.model._meta.verbose_name,
|
||||||
'form': form,
|
'form': form,
|
||||||
|
@ -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.utils import get_viewname, normalize_querydict, prepare_cloned_fields
|
||||||
from utilities.views import GetReturnURLMixin
|
from utilities.views import GetReturnURLMixin
|
||||||
from .base import BaseObjectView
|
from .base import BaseObjectView
|
||||||
|
from .utils import get_prerequisite_model
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ComponentCreateView',
|
'ComponentCreateView',
|
||||||
@ -342,12 +343,19 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView):
|
|||||||
form = self.form(instance=obj, initial=initial_data)
|
form = self.form(instance=obj, initial=initial_data)
|
||||||
restrict_form_fields(form, request.user)
|
restrict_form_fields(form, request.user)
|
||||||
|
|
||||||
return render(request, self.template_name, {
|
context = {
|
||||||
'object': obj,
|
'object': obj,
|
||||||
'form': form,
|
'form': form,
|
||||||
'return_url': self.get_return_url(request, obj),
|
'return_url': self.get_return_url(request, obj),
|
||||||
**self.get_extra_context(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):
|
def post(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
12
netbox/netbox/views/generic/utils.py
Normal file
12
netbox/netbox/views/generic/utils.py
Normal file
@ -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
|
@ -40,6 +40,10 @@ Context:
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if required_model %}
|
||||||
|
{% include 'inc/missing_prerequisites.html' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<form action="" method="post" enctype="multipart/form-data" class="form-object-edit mt-5">
|
<form action="" method="post" enctype="multipart/form-data" class="form-object-edit mt-5">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
|
@ -100,6 +100,12 @@ Context:
|
|||||||
<input type="hidden" name="return_url" value="{% if return_url %}{{ return_url }}{% else %}{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}{% endif %}" />
|
<input type="hidden" name="return_url" value="{% if return_url %}{{ return_url }}{% else %}{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}{% endif %}" />
|
||||||
|
|
||||||
{# Object table #}
|
{# Object table #}
|
||||||
|
|
||||||
|
{% if required_model %}
|
||||||
|
{% include 'inc/missing_prerequisites.html' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body" id="object_list">
|
<div class="card-body" id="object_list">
|
||||||
{% include 'htmx/table.html' %}
|
{% include 'htmx/table.html' %}
|
||||||
|
5
netbox/templates/inc/missing_prerequisites.html
Normal file
5
netbox/templates/inc/missing_prerequisites.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{% load buttons %}
|
||||||
|
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<i class="mdi mdi-alert"></i> <strong>Note:</strong> Before you can add a {{ model|meta:"verbose_name" }} you must first add a {{ required_model|meta:"verbose_name" }} here {% add_button required_model %}
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user