From 91efa14dbb6d023aa073fa273d6f87a625a867b1 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Tue, 23 Apr 2024 14:03:34 -0500 Subject: [PATCH 1/7] Fix cable edit form with single unterminated cable --- netbox/dcim/views.py | 21 ++++++--- netbox/netbox/views/generic/object_views.py | 3 +- netbox/templates/dcim/cable_edit.html | 47 ++++++++++++++++++--- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index ce4bb5750d8..ddbbb764288 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -23,6 +23,7 @@ from netbox.views import generic from tenancy.views import ObjectContactsView from utilities.forms import ConfirmationForm +from utilities.htmx import is_htmx from utilities.paginator import EnhancedPaginator, get_paginate_count from utilities.permissions import get_permission_for_model from utilities.query_functions import CollateAsChar @@ -3183,6 +3184,7 @@ class CableView(generic.ObjectView): class CableEditView(generic.ObjectEditView): queryset = Cable.objects.all() template_name = 'dcim/cable_edit.html' + htmx_template_name = 'dcim/cable_edit.html' def dispatch(self, request, *args, **kwargs): @@ -3195,22 +3197,29 @@ def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) - def get_object(self, **kwargs): + def alter_object(self, obj, request, url_args, url_kwargs): """ Hack into get_object() to set the form class when editing an existing Cable, since ObjectEditView doesn't currently provide a hook for dynamic class resolution. """ - obj = super().get_object(**kwargs) - + a_terminations_type = request.GET.get('a_terminations_type') + b_terminations_type = request.GET.get('b_terminations_type') if obj.pk: # TODO: Optimize this logic termination_a = obj.terminations.filter(cable_end='A').first() - a_type = termination_a.termination._meta.model if termination_a else None + a_type = termination_a.termination._meta.model if termination_a else ( + CABLE_TERMINATION_TYPES.get(a_terminations_type) + ) termination_b = obj.terminations.filter(cable_end='B').first() - b_type = termination_b.termination._meta.model if termination_b else None + b_type = termination_b.termination._meta.model if termination_b else ( + CABLE_TERMINATION_TYPES.get(b_terminations_type) + ) + + self.skip_htmx = True + self.form = forms.get_cable_form(a_type, b_type) - return obj + return super().alter_object(obj, request, url_args, url_kwargs) def get_extra_addanother_params(self, request): diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py index 6277e1c5b0a..e352f5f2af9 100644 --- a/netbox/netbox/views/generic/object_views.py +++ b/netbox/netbox/views/generic/object_views.py @@ -167,6 +167,7 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): """ template_name = 'generic/object_edit.html' form = None + skip_htmx = False def dispatch(self, request, *args, **kwargs): # Determine required permission based on whether we are editing an existing object @@ -227,7 +228,7 @@ def get(self, request, *args, **kwargs): restrict_form_fields(form, request.user) # If this is an HTMX request, return only the rendered form HTML - if is_htmx(request): + if is_htmx(request) and not self.skip_htmx: return render(request, 'htmx/form.html', { 'form': form, }) diff --git a/netbox/templates/dcim/cable_edit.html b/netbox/templates/dcim/cable_edit.html index 14d763dc3b0..f7058e47d92 100644 --- a/netbox/templates/dcim/cable_edit.html +++ b/netbox/templates/dcim/cable_edit.html @@ -5,9 +5,8 @@ {% load i18n %} {% block form %} - {# A side termination #} -
+
{% trans "A Side" %}
@@ -20,11 +19,30 @@
{% trans "A Side" %}
{% if 'termination_a_circuit' in form.fields %} {% render_field form.termination_a_circuit %} {% endif %} - {% render_field form.a_terminations %} + {% if 'a_terminations' in form.fields %} + {% render_field form.a_terminations %} + {% elif 'b_terminations' in form.fields %} +
+ +
+ + + + +
+
+ {% else %} +
+ +
Cannot initialize dynamic cable termination selection form
+ +
This field is required.
+
+ {% endif %}
{# B side termination #} -
+
{% trans "B Side" %}
@@ -37,7 +55,26 @@
{% trans "B Side" %}
{% if 'termination_b_circuit' in form.fields %} {% render_field form.termination_b_circuit %} {% endif %} - {% render_field form.b_terminations %} + {% if 'b_terminations' in form.fields %} + {% render_field form.b_terminations %} + {% elif 'a_terminations' in form.fields %} +
+ +
+ + + + +
+
+ {% else %} +
+ +
Cannot initialize dynamic cable termination selection form
+ +
This field is required.
+
+ {% endif %}
{# Cable attributes #} From 7a54302a653d03d08104a8cedb8ae408a781f4fa Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Tue, 23 Apr 2024 14:04:37 -0500 Subject: [PATCH 2/7] Minor tweaks --- netbox/dcim/views.py | 1 - netbox/templates/dcim/cable_edit.html | 18 ++---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index ddbbb764288..d3ea3acd73b 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -23,7 +23,6 @@ from netbox.views import generic from tenancy.views import ObjectContactsView from utilities.forms import ConfirmationForm -from utilities.htmx import is_htmx from utilities.paginator import EnhancedPaginator, get_paginate_count from utilities.permissions import get_permission_for_model from utilities.query_functions import CollateAsChar diff --git a/netbox/templates/dcim/cable_edit.html b/netbox/templates/dcim/cable_edit.html index f7058e47d92..c27ca299236 100644 --- a/netbox/templates/dcim/cable_edit.html +++ b/netbox/templates/dcim/cable_edit.html @@ -21,7 +21,7 @@
{% trans "A Side" %}
{% endif %} {% if 'a_terminations' in form.fields %} {% render_field form.a_terminations %} - {% elif 'b_terminations' in form.fields %} + {% else %}
@@ -31,13 +31,6 @@
{% trans "A Side" %}
- {% else %} -
- -
Cannot initialize dynamic cable termination selection form
- -
This field is required.
-
{% endif %}
@@ -57,7 +50,7 @@
{% trans "B Side" %}
{% endif %} {% if 'b_terminations' in form.fields %} {% render_field form.b_terminations %} - {% elif 'a_terminations' in form.fields %} + {% else %}
@@ -67,13 +60,6 @@
{% trans "B Side" %}
- {% else %} -
- -
Cannot initialize dynamic cable termination selection form
- -
This field is required.
-
{% endif %}
From f37cb9bfd32f95b3d279a41c4755fd3de9259a74 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Tue, 23 Apr 2024 15:16:06 -0500 Subject: [PATCH 3/7] Instead of skipping HTMX, override the template & move form template to an "htmx" template --- netbox/dcim/views.py | 4 +- netbox/netbox/views/generic/object_views.py | 6 +- netbox/templates/dcim/cable_edit.html | 110 +------------------ netbox/templates/dcim/htmx/cable_edit.html | 116 ++++++++++++++++++++ 4 files changed, 121 insertions(+), 115 deletions(-) create mode 100644 netbox/templates/dcim/htmx/cable_edit.html diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index d3ea3acd73b..320e52680d0 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -3183,7 +3183,7 @@ class CableView(generic.ObjectView): class CableEditView(generic.ObjectEditView): queryset = Cable.objects.all() template_name = 'dcim/cable_edit.html' - htmx_template_name = 'dcim/cable_edit.html' + htmx_template_name = 'dcim/htmx/cable_edit.html' def dispatch(self, request, *args, **kwargs): @@ -3214,8 +3214,6 @@ def alter_object(self, obj, request, url_args, url_kwargs): CABLE_TERMINATION_TYPES.get(b_terminations_type) ) - self.skip_htmx = True - self.form = forms.get_cable_form(a_type, b_type) return super().alter_object(obj, request, url_args, url_kwargs) diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py index e352f5f2af9..21d740b8e49 100644 --- a/netbox/netbox/views/generic/object_views.py +++ b/netbox/netbox/views/generic/object_views.py @@ -167,7 +167,7 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): """ template_name = 'generic/object_edit.html' form = None - skip_htmx = False + htmx_template_name = 'htmx/form.html' def dispatch(self, request, *args, **kwargs): # Determine required permission based on whether we are editing an existing object @@ -228,8 +228,8 @@ def get(self, request, *args, **kwargs): restrict_form_fields(form, request.user) # If this is an HTMX request, return only the rendered form HTML - if is_htmx(request) and not self.skip_htmx: - return render(request, 'htmx/form.html', { + if is_htmx(request): + return render(request, self.htmx_template_name, { 'form': form, }) diff --git a/netbox/templates/dcim/cable_edit.html b/netbox/templates/dcim/cable_edit.html index c27ca299236..fbe877d87e7 100644 --- a/netbox/templates/dcim/cable_edit.html +++ b/netbox/templates/dcim/cable_edit.html @@ -1,113 +1,5 @@ {% extends 'generic/object_edit.html' %} -{% load static %} -{% load helpers %} -{% load form_helpers %} -{% load i18n %} {% block form %} - {# A side termination #} -
-
-
{% trans "A Side" %}
-
- {% if 'termination_a_device' in form.fields %} - {% render_field form.termination_a_device %} - {% endif %} - {% if 'termination_a_powerpanel' in form.fields %} - {% render_field form.termination_a_powerpanel %} - {% endif %} - {% if 'termination_a_circuit' in form.fields %} - {% render_field form.termination_a_circuit %} - {% endif %} - {% if 'a_terminations' in form.fields %} - {% render_field form.a_terminations %} - {% else %} -
- -
- - - - -
-
- {% endif %} -
- - {# B side termination #} -
-
-
{% trans "B Side" %}
-
- {% if 'termination_b_device' in form.fields %} - {% render_field form.termination_b_device %} - {% endif %} - {% if 'termination_b_powerpanel' in form.fields %} - {% render_field form.termination_b_powerpanel %} - {% endif %} - {% if 'termination_b_circuit' in form.fields %} - {% render_field form.termination_b_circuit %} - {% endif %} - {% if 'b_terminations' in form.fields %} - {% render_field form.b_terminations %} - {% else %} -
- -
- - - - -
-
- {% endif %} -
- - {# Cable attributes #} -
-
-
{% trans "Cable" %}
-
- {% render_field form.status %} - {% render_field form.type %} - {% render_field form.label %} - {% render_field form.description %} - {% render_field form.color %} -
- -
- {{ form.length }} -
-
- {{ form.length_unit }} -
-
-
- {% render_field form.tags %} -
- -
-
-
{% trans "Tenancy" %}
-
- {% render_field form.tenant_group %} - {% render_field form.tenant %} -
- - {% if form.custom_fields %} -
-
-
{% trans "Custom Fields" %}
-
- {% render_custom_fields form %} -
- {% endif %} - - {% if form.comments %} -
-
{% trans "Comments" %}
- {% render_field form.comments %} -
- {% endif %} - + {% include 'dcim/htmx/cable_edit.html' %} {% endblock %} diff --git a/netbox/templates/dcim/htmx/cable_edit.html b/netbox/templates/dcim/htmx/cable_edit.html new file mode 100644 index 00000000000..6fcbd71e4aa --- /dev/null +++ b/netbox/templates/dcim/htmx/cable_edit.html @@ -0,0 +1,116 @@ +{% load static %} +{% load helpers %} +{% load form_helpers %} +{% load i18n %} + + +{# A side termination #} +
+
+
{% trans "A Side" %}
+
+ {% if 'termination_a_device' in form.fields %} + {% render_field form.termination_a_device %} + {% endif %} + {% if 'termination_a_powerpanel' in form.fields %} + {% render_field form.termination_a_powerpanel %} + {% endif %} + {% if 'termination_a_circuit' in form.fields %} + {% render_field form.termination_a_circuit %} + {% endif %} + {% if 'a_terminations' in form.fields %} + {% render_field form.a_terminations %} + {% else %} +
+ +
+ +
+
+ {% endif %} +
+ +{# B side termination #} +
+
+
{% trans "B Side" %}
+
+ {% if 'termination_b_device' in form.fields %} + {% render_field form.termination_b_device %} + {% endif %} + {% if 'termination_b_powerpanel' in form.fields %} + {% render_field form.termination_b_powerpanel %} + {% endif %} + {% if 'termination_b_circuit' in form.fields %} + {% render_field form.termination_b_circuit %} + {% endif %} + {% if 'b_terminations' in form.fields %} + {% render_field form.b_terminations %} + {% else %} +
+ +
+ +
+
+ {% endif %} +
+ +{# Cable attributes #} +
+
+
{% trans "Cable" %}
+
+ {% render_field form.status %} + {% render_field form.type %} + {% render_field form.label %} + {% render_field form.description %} + {% render_field form.color %} +
+ +
+ {{ form.length }} +
+
+ {{ form.length_unit }} +
+
+
+ {% render_field form.tags %} +
+ +
+
+
{% trans "Tenancy" %}
+
+ {% render_field form.tenant_group %} + {% render_field form.tenant %} +
+ +{% if form.custom_fields %} +
+
+
{% trans "Custom Fields" %}
+
+ {% render_custom_fields form %} +
+{% endif %} + +{% if form.comments %} +
+
{% trans "Comments" %}
+ {% render_field form.comments %} +
+{% endif %} \ No newline at end of file From fc3e52d37b3cfe2851abd4f0563b274191ad9907 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 29 Apr 2024 16:43:17 -0400 Subject: [PATCH 4/7] Use HTMXSelect widget for A/B type selection --- netbox/dcim/forms/connections.py | 17 +++++++++--- netbox/dcim/forms/model_forms.py | 26 +++++++++++++++++-- netbox/templates/dcim/htmx/cable_edit.html | 30 +++------------------- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/netbox/dcim/forms/connections.py b/netbox/dcim/forms/connections.py index 854c5ebedd4..333ac1ba694 100644 --- a/netbox/dcim/forms/connections.py +++ b/netbox/dcim/forms/connections.py @@ -1,4 +1,5 @@ from django import forms +from django.contrib.contenttypes.models import ContentType from django.utils.translation import gettext_lazy as _ from circuits.models import Circuit, CircuitTermination @@ -82,14 +83,22 @@ def __new__(mcs, name, bases, attrs): class _CableForm(CableForm, metaclass=FormMetaclass): - def __init__(self, *args, **kwargs): + def __init__(self, *args, initial=None, **kwargs): + + initial = initial or {} + if a_type: + ct = ContentType.objects.get_for_model(a_type) + initial['a_terminations_type'] = f'{ct.app_label}.{ct.model}' + if b_type: + ct = ContentType.objects.get_for_model(b_type) + initial['b_terminations_type'] = f'{ct.app_label}.{ct.model}' # TODO: Temporary hack to work around list handling limitations with utils.normalize_querydict() for field_name in ('a_terminations', 'b_terminations'): - if field_name in kwargs.get('initial', {}) and type(kwargs['initial'][field_name]) is not list: - kwargs['initial'][field_name] = [kwargs['initial'][field_name]] + if field_name in initial and type(initial[field_name]) is not list: + initial[field_name] = [initial[field_name]] - super().__init__(*args, **kwargs) + super().__init__(*args, initial=initial, **kwargs) if self.instance and self.instance.pk: # Initialize A/B terminations when modifying an existing Cable instance diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index cee8fcfba87..b25c43b1235 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -616,14 +616,36 @@ def __init__(self, *args, **kwargs): self.fields['adopt_components'].disabled = True +def get_termination_type_choices(): + return [ + (None, '---------'), + *[ + (f'{ct.app_label}.{ct.model}', ct.model_class()._meta.verbose_name.title()) + for ct in ContentType.objects.filter(CABLE_TERMINATION_MODELS) + ] + ] + + class CableForm(TenancyForm, NetBoxModelForm): + a_terminations_type = forms.ChoiceField( + choices=get_termination_type_choices, + required=False, + widget=HTMXSelect(), + label=_('Type') + ) + b_terminations_type = forms.ChoiceField( + choices=get_termination_type_choices, + required=False, + widget=HTMXSelect(), + label=_('Type') + ) comments = CommentField() class Meta: model = Cable fields = [ - 'type', 'status', 'tenant_group', 'tenant', 'label', 'color', 'length', 'length_unit', 'description', - 'comments', 'tags', + 'a_terminations_type', 'b_terminations_type', 'type', 'status', 'tenant_group', 'tenant', 'label', 'color', + 'length', 'length_unit', 'description', 'comments', 'tags', ] error_messages = { 'length': { diff --git a/netbox/templates/dcim/htmx/cable_edit.html b/netbox/templates/dcim/htmx/cable_edit.html index 6fcbd71e4aa..5f22fe372d3 100644 --- a/netbox/templates/dcim/htmx/cable_edit.html +++ b/netbox/templates/dcim/htmx/cable_edit.html @@ -9,6 +9,7 @@
{% trans "A Side" %}
+ {% render_field form.a_terminations_type %} {% if 'termination_a_device' in form.fields %} {% render_field form.termination_a_device %} {% endif %} @@ -20,19 +21,6 @@
{% trans "A Side" %}
{% endif %} {% if 'a_terminations' in form.fields %} {% render_field form.a_terminations %} - {% else %} -
- -
- -
-
{% endif %} @@ -41,6 +29,7 @@
{% trans "A Side" %}
{% trans "B Side" %}
+ {% render_field form.b_terminations_type %} {% if 'termination_b_device' in form.fields %} {% render_field form.termination_b_device %} {% endif %} @@ -51,20 +40,7 @@
{% trans "B Side" %}
{% render_field form.termination_b_circuit %} {% endif %} {% if 'b_terminations' in form.fields %} - {% render_field form.b_terminations %} - {% else %} -
- -
- -
-
+ {% render_field form.b_terminations %} {% endif %} From 297ab4a9db7ef3a84bda6e0019b1af18f9103f90 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 29 Apr 2024 17:27:35 -0400 Subject: [PATCH 5/7] Infer A/B termination types from POST data --- netbox/dcim/forms/connections.py | 4 ++-- netbox/dcim/forms/model_forms.py | 14 +++++--------- netbox/dcim/views.py | 21 ++++++++++----------- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/netbox/dcim/forms/connections.py b/netbox/dcim/forms/connections.py index 333ac1ba694..90a3d6ce0a1 100644 --- a/netbox/dcim/forms/connections.py +++ b/netbox/dcim/forms/connections.py @@ -109,7 +109,7 @@ def clean(self): super().clean() # Set the A/B terminations on the Cable instance - self.instance.a_terminations = self.cleaned_data['a_terminations'] - self.instance.b_terminations = self.cleaned_data['b_terminations'] + self.instance.a_terminations = self.cleaned_data.get('a_terminations', []) + self.instance.b_terminations = self.cleaned_data.get('b_terminations', []) return _CableForm diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index b25c43b1235..cc7100e3c1c 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -13,8 +13,7 @@ from tenancy.forms import TenancyForm from utilities.forms import BootstrapMixin, add_blank_choice from utilities.forms.fields import ( - CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, - NumericArrayField, SlugField, + CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, NumericArrayField, SlugField, ) from utilities.forms.widgets import APISelect, ClearableFileInput, HTMXSelect, NumberWithOptions, SelectWithPK from virtualization.models import Cluster @@ -617,13 +616,10 @@ def __init__(self, *args, **kwargs): def get_termination_type_choices(): - return [ - (None, '---------'), - *[ - (f'{ct.app_label}.{ct.model}', ct.model_class()._meta.verbose_name.title()) - for ct in ContentType.objects.filter(CABLE_TERMINATION_MODELS) - ] - ] + return add_blank_choice([ + (f'{ct.app_label}.{ct.model}', ct.model_class()._meta.verbose_name.title()) + for ct in ContentType.objects.filter(CABLE_TERMINATION_MODELS) + ]) class CableForm(TenancyForm, NetBoxModelForm): diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 320e52680d0..a2e9ef12ad0 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -3201,18 +3201,17 @@ def alter_object(self, obj, request, url_args, url_kwargs): Hack into get_object() to set the form class when editing an existing Cable, since ObjectEditView doesn't currently provide a hook for dynamic class resolution. """ - a_terminations_type = request.GET.get('a_terminations_type') - b_terminations_type = request.GET.get('b_terminations_type') + a_terminations_type = request.POST.get('a_terminations_type') or request.GET.get('a_terminations_type') + b_terminations_type = request.POST.get('b_terminations_type') or request.GET.get('b_terminations_type') if obj.pk: - # TODO: Optimize this logic - termination_a = obj.terminations.filter(cable_end='A').first() - a_type = termination_a.termination._meta.model if termination_a else ( - CABLE_TERMINATION_TYPES.get(a_terminations_type) - ) - termination_b = obj.terminations.filter(cable_end='B').first() - b_type = termination_b.termination._meta.model if termination_b else ( - CABLE_TERMINATION_TYPES.get(b_terminations_type) - ) + if not a_terminations_type and (termination_a := obj.terminations.filter(cable_end='A').first()): + a_type = termination_a.termination._meta.model + else: + a_type = CABLE_TERMINATION_TYPES.get(a_terminations_type) + if not b_terminations_type and (termination_b := obj.terminations.filter(cable_end='B').first()): + b_type = termination_b.termination._meta.model + else: + b_type = CABLE_TERMINATION_TYPES.get(b_terminations_type) self.form = forms.get_cable_form(a_type, b_type) From a16564f9fcadb06f749a2d02fbf1cf2ad9f79fd3 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Tue, 30 Apr 2024 08:29:19 -0500 Subject: [PATCH 6/7] Fix saving cable which results in resetting of the termination type fields --- netbox/dcim/views.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index a2e9ef12ad0..eb81e99c567 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -3189,9 +3189,11 @@ def dispatch(self, request, *args, **kwargs): # If creating a new Cable, initialize the form class using URL query params if 'pk' not in kwargs: + a_terminations_type = request.POST.get('a_terminations_type') or request.GET.get('a_terminations_type') + b_terminations_type = request.POST.get('b_terminations_type') or request.GET.get('b_terminations_type') self.form = forms.get_cable_form( - a_type=CABLE_TERMINATION_TYPES.get(request.GET.get('a_terminations_type')), - b_type=CABLE_TERMINATION_TYPES.get(request.GET.get('b_terminations_type')) + a_type=CABLE_TERMINATION_TYPES.get(a_terminations_type), + b_type=CABLE_TERMINATION_TYPES.get(b_terminations_type) ) return super().dispatch(request, *args, **kwargs) From b8a2c62e9e8968a22c34b50e186ee5ebbc7af2d4 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 30 Apr 2024 12:02:36 -0400 Subject: [PATCH 7/7] Condense view logic --- netbox/dcim/views.py | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index eb81e99c567..805e9d88113 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -3185,37 +3185,25 @@ class CableEditView(generic.ObjectEditView): template_name = 'dcim/cable_edit.html' htmx_template_name = 'dcim/htmx/cable_edit.html' - def dispatch(self, request, *args, **kwargs): - - # If creating a new Cable, initialize the form class using URL query params - if 'pk' not in kwargs: - a_terminations_type = request.POST.get('a_terminations_type') or request.GET.get('a_terminations_type') - b_terminations_type = request.POST.get('b_terminations_type') or request.GET.get('b_terminations_type') - self.form = forms.get_cable_form( - a_type=CABLE_TERMINATION_TYPES.get(a_terminations_type), - b_type=CABLE_TERMINATION_TYPES.get(b_terminations_type) - ) - - return super().dispatch(request, *args, **kwargs) - def alter_object(self, obj, request, url_args, url_kwargs): """ - Hack into get_object() to set the form class when editing an existing Cable, since ObjectEditView + Hack into alter_object() to set the form class when editing an existing Cable, since ObjectEditView doesn't currently provide a hook for dynamic class resolution. """ - a_terminations_type = request.POST.get('a_terminations_type') or request.GET.get('a_terminations_type') - b_terminations_type = request.POST.get('b_terminations_type') or request.GET.get('b_terminations_type') + a_terminations_type = CABLE_TERMINATION_TYPES.get( + request.GET.get('a_terminations_type') or request.POST.get('a_terminations_type') + ) + b_terminations_type = CABLE_TERMINATION_TYPES.get( + request.GET.get('b_terminations_type') or request.POST.get('b_terminations_type') + ) + if obj.pk: if not a_terminations_type and (termination_a := obj.terminations.filter(cable_end='A').first()): - a_type = termination_a.termination._meta.model - else: - a_type = CABLE_TERMINATION_TYPES.get(a_terminations_type) + a_terminations_type = termination_a.termination._meta.model if not b_terminations_type and (termination_b := obj.terminations.filter(cable_end='B').first()): - b_type = termination_b.termination._meta.model - else: - b_type = CABLE_TERMINATION_TYPES.get(b_terminations_type) + b_terminations_type = termination_b.termination._meta.model - self.form = forms.get_cable_form(a_type, b_type) + self.form = forms.get_cable_form(a_terminations_type, b_terminations_type) return super().alter_object(obj, request, url_args, url_kwargs)