Просмотр исходного кода

Fixes #7153: Allow clearing of assigned device type images

jeremystretch 4 лет назад
Родитель
Сommit
a1110b07de

+ 2 - 0
docs/release-notes/version-3.0.md

@@ -1,8 +1,10 @@
 # NetBox v3.0
 
 ## v3.0.2 (FUTURE)
+
 * [#7131](https://github.com/netbox-community/netbox/issues/7131) - Fix issue where Site fields were hidden when editing a VLAN group
 * [#7148](https://github.com/netbox-community/netbox/issues/7148) - Fix issue where static query parameters with multiple values were not queried properly
+* [#7153](https://github.com/netbox-community/netbox/issues/7153) - Allow clearing of assigned device type images
 
 ---
 

+ 6 - 6
netbox/dcim/forms.py

@@ -23,10 +23,10 @@ from tenancy.forms import TenancyFilterForm, TenancyForm
 from tenancy.models import Tenant
 from utilities.forms import (
     APISelect, APISelectMultiple, add_blank_choice, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
-    ColorField, CommentField, CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVTypedChoiceField,
-    DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableNameField, form_from_model, JSONField,
-    NumericArrayField, SelectWithPK, SmallTextarea, SlugField, StaticSelect, StaticSelectMultiple, TagFilterField,
-    BOOLEAN_WITH_BLANK_CHOICES,
+    ClearableFileInput, ColorField, CommentField, CSVChoiceField, CSVContentTypeField, CSVModelChoiceField,
+    CSVTypedChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableNameField, form_from_model,
+    JSONField, NumericArrayField, SelectWithPK, SmallTextarea, SlugField, StaticSelect, StaticSelectMultiple,
+    TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
 )
 from virtualization.models import Cluster, ClusterGroup
 from .choices import *
@@ -1271,10 +1271,10 @@ class DeviceTypeForm(BootstrapMixin, CustomFieldModelForm):
         )
         widgets = {
             'subdevice_role': StaticSelect(),
-            'front_image': forms.ClearableFileInput(attrs={
+            'front_image': ClearableFileInput(attrs={
                 'accept': DEVICETYPE_IMAGE_FORMATS
             }),
-            'rear_image': forms.ClearableFileInput(attrs={
+            'rear_image': ClearableFileInput(attrs={
                 'accept': DEVICETYPE_IMAGE_FORMATS
             })
         }

+ 22 - 12
netbox/templates/utilities/render_field.html

@@ -86,18 +86,28 @@
         </div>
     </div>
 
-{% elif field|widget_type == 'fileinput' or field|widget_type == 'clearablefileinput' %}
-    <div class="input-group mb-3">
-        <input
-            class="form-control"
-            type="file"
-            name="{{ field.name }}"
-            placeholder="{{ field.placeholder }}"
-            id="id_{{ field.name }}"
-            accept="{{ field.field.widget.attrs.accept }}"
-            {% if field.is_required %}required{% endif %}
-        />
-        <label for="{{ field.id_for_label }}" class="input-group-text">{{ field.label|bettertitle }}</label>
+{% elif field|widget_type == 'fileinput' %}
+  <div class="input-group mb-3">
+    <input
+        class="form-control"
+        type="file"
+        name="{{ field.name }}"
+        placeholder="{{ field.placeholder }}"
+        id="id_{{ field.name }}"
+        accept="{{ field.field.widget.attrs.accept }}"
+        {% if field.is_required %}required{% endif %}
+    />
+    <label for="{{ field.id_for_label }}" class="input-group-text">{{ field.label|bettertitle }}</label>
+  </div>
+
+{% elif field|widget_type == 'clearablefileinput' %}
+    <div class="row mb-3">
+        <label for="{{ field.id_for_label }}" class="form-label col col-md-3 text-lg-end{% if field.field.required %} required{% endif %}">
+            {{ field.label }}
+        </label>
+        <div class="col col-md-9">
+            {{ field }}
+        </div>
     </div>
 
 {% elif field|widget_type == 'selectmultiple' %}

+ 2 - 2
netbox/utilities/forms/forms.py

@@ -4,7 +4,7 @@ import re
 import yaml
 from django import forms
 
-from .widgets import APISelect, APISelectMultiple, StaticSelect
+from .widgets import APISelect, APISelectMultiple, ClearableFileInput, StaticSelect
 
 
 __all__ = (
@@ -29,12 +29,12 @@ class BootstrapMixin(forms.BaseForm):
 
         exempt_widgets = [
             forms.CheckboxInput,
-            forms.ClearableFileInput,
             forms.FileInput,
             forms.RadioSelect,
             forms.Select,
             APISelect,
             APISelectMultiple,
+            ClearableFileInput,
             StaticSelect,
         ]
 

+ 8 - 0
netbox/utilities/forms/widgets.py

@@ -12,6 +12,7 @@ __all__ = (
     'APISelect',
     'APISelectMultiple',
     'BulkEditNullBooleanSelect',
+    'ClearableFileInput',
     'ColorSelect',
     'ContentTypeSelect',
     'DatePicker',
@@ -135,6 +136,13 @@ class NumericArrayField(SimpleArrayField):
         return super().to_python(value)
 
 
+class ClearableFileInput(forms.ClearableFileInput):
+    """
+    Override Django's stock ClearableFileInput with a custom template.
+    """
+    template_name = 'widgets/clearable_file_input.html'
+
+
 class APISelect(SelectWithDisabled):
     """
     A select widget populated via an API call

+ 24 - 0
netbox/utilities/templates/widgets/clearable_file_input.html

@@ -0,0 +1,24 @@
+<div class="row">
+  <div class="col-6">
+    {% if widget.is_initial %}
+      <a href="{{ widget.value.url }}">{{ widget.value }}</a>
+      {% if not widget.required %}
+        <br />
+        <input type="checkbox" name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}"{% if widget.attrs.disabled %} disabled{% endif %}>
+        <label for="{{ widget.checkbox_id }}">{{ widget.clear_checkbox_label }}</label>
+      {% endif %}
+    {% else %}
+      <span class="text-muted">None assigned</span>
+    {% endif %}
+  </div>
+  <div class="col-6">
+    <input
+  class="form-control"
+  type="{{ widget.type }}"
+  name="{{ widget.name }}"
+  id="id_{{ widget.name }}"
+  accept="{{ widget.attrs.accept }}"
+  {% if widget.required %}required{% endif %}
+/>
+  </div>
+</div>