mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Fixes #7153: Allow clearing of assigned device type images
This commit is contained in:
@ -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
|
||||
|
||||
---
|
||||
|
||||
|
@ -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
|
||||
})
|
||||
}
|
||||
|
@ -86,7 +86,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% elif field|widget_type == 'fileinput' or field|widget_type == 'clearablefileinput' %}
|
||||
{% elif field|widget_type == 'fileinput' %}
|
||||
<div class="input-group mb-3">
|
||||
<input
|
||||
class="form-control"
|
||||
@ -100,6 +100,16 @@
|
||||
<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' %}
|
||||
<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 %}">
|
||||
|
@ -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,
|
||||
]
|
||||
|
||||
|
@ -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
netbox/utilities/templates/widgets/clearable_file_input.html
Normal file
24
netbox/utilities/templates/widgets/clearable_file_input.html
Normal file
@ -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>
|
Reference in New Issue
Block a user