Skip to content

Commit c63c6e3

Browse files
committed
adds image attachment list view #11932
1 parent 3eba65b commit c63c6e3

File tree

6 files changed

+57
-41
lines changed

6 files changed

+57
-41
lines changed

netbox/extras/forms/filtersets.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from netbox.forms.base import NetBoxModelFilterSetForm
1212
from tenancy.models import Tenant, TenantGroup
1313
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, FilterForm, add_blank_choice
14-
from utilities.forms.fields import ContentTypeMultipleChoiceField, DynamicModelMultipleChoiceField, TagFilterField
14+
from utilities.forms.fields import ContentTypeChoiceField, ContentTypeMultipleChoiceField, DynamicModelMultipleChoiceField, TagFilterField
1515
from utilities.forms.widgets import APISelectMultiple, DateTimePicker
1616
from virtualization.models import Cluster, ClusterGroup, ClusterType
1717
from .mixins import SavedFiltersMixin
@@ -22,6 +22,7 @@
2222
'CustomFieldFilterForm',
2323
'CustomLinkFilterForm',
2424
'ExportTemplateFilterForm',
25+
'ImageAttachmentFilterForm',
2526
'JournalEntryFilterForm',
2627
'LocalConfigContextFilterForm',
2728
'ObjectChangeFilterForm',
@@ -137,6 +138,22 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
137138
)
138139

139140

141+
class ImageAttachmentFilterForm(SavedFiltersMixin, FilterForm):
142+
fieldsets = (
143+
(None, ('q', 'filter_id')),
144+
('Attributes', ('content_type', 'name',)),
145+
)
146+
147+
content_type = ContentTypeChoiceField(
148+
queryset=ContentType.objects.filter(FeatureQuery('custom_fields').get_query()),
149+
required=False
150+
)
151+
152+
name = forms.CharField(
153+
required=False
154+
)
155+
156+
140157
class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
141158
fieldsets = (
142159
(None, ('q', 'filter_id')),

netbox/extras/tables/tables.py

+26-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import json
2-
31
import django_tables2 as tables
42
from django.conf import settings
53

4+
import json
65
from extras.models import *
76
from netbox.tables import NetBoxTable, columns
87
from .template_code import *
@@ -13,6 +12,7 @@
1312
'CustomFieldTable',
1413
'CustomLinkTable',
1514
'ExportTemplateTable',
15+
'ImageAttachmentTable',
1616
'JournalEntryTable',
1717
'ObjectChangeTable',
1818
'SavedFilterTable',
@@ -86,6 +86,30 @@ class Meta(NetBoxTable.Meta):
8686
)
8787

8888

89+
class ImageAttachmentTable(NetBoxTable):
90+
id = tables.Column(
91+
linkify=False
92+
)
93+
94+
content_type = columns.ContentTypeColumn()
95+
96+
parent = tables.Column(
97+
linkify=True
98+
)
99+
100+
size = tables.Column(
101+
verbose_name='Size (bytes)'
102+
)
103+
104+
class Meta(NetBoxTable.Meta):
105+
model = ImageAttachment
106+
fields = (
107+
'pk', 'content_type', 'parent', 'image', 'name', 'image_height', 'image_width', 'size', 'created',
108+
'last_updated',
109+
)
110+
default_columns = ('content_type', 'parent', 'image', 'name', 'size', 'created')
111+
112+
89113
class SavedFilterTable(NetBoxTable):
90114
name = tables.Column(
91115
linkify=True

netbox/extras/urls.py

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
path('config-templates/<int:pk>/', include(get_model_urls('extras', 'configtemplate'))),
7474

7575
# Image attachments
76+
path('image-attachments/', views.ImageAttachmentListView.as_view(), name='imageattachment_list'),
7677
path('image-attachments/add/', views.ImageAttachmentEditView.as_view(), name='imageattachment_add'),
7778
path('image-attachments/<int:pk>/', include(get_model_urls('extras', 'imageattachment'))),
7879

netbox/extras/views.py

+8
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,14 @@ def get_extra_context(self, request, instance):
577577
# Image attachments
578578
#
579579

580+
class ImageAttachmentListView(generic.ObjectListView):
581+
queryset = ImageAttachment.objects.all()
582+
filterset = filtersets.ImageAttachmentFilterSet
583+
filterset_form = forms.ImageAttachmentFilterForm
584+
table = tables.ImageAttachmentTable
585+
actions = ('export',)
586+
587+
580588
@register_model_view(ImageAttachment, 'edit')
581589
class ImageAttachmentEditView(generic.ObjectEditView):
582590
queryset = ImageAttachment.objects.all()

netbox/netbox/navigation/menu.py

+1
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@
290290
get_model_item('extras', 'customfield', _('Custom Fields')),
291291
get_model_item('extras', 'customlink', _('Custom Links')),
292292
get_model_item('extras', 'exporttemplate', _('Export Templates')),
293+
get_model_item('extras', 'imageattachment', _('Image Attachments'), actions=()),
293294
get_model_item('extras', 'savedfilter', _('Saved Filters')),
294295
get_model_item('extras', 'tag', 'Tags'),
295296
),

netbox/templates/inc/panels/image_attachments.html

+3-38
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,9 @@
44
<h5 class="card-header">
55
Images
66
</h5>
7-
<div class="card-body">
8-
{% with images=object.images.all %}
9-
{% if images.exists %}
10-
<table class="table table-hover">
11-
<tr>
12-
<th>Name</th>
13-
<th>Size</th>
14-
<th>Created</th>
15-
<th></th>
16-
</tr>
17-
{% for attachment in images %}
18-
<tr{% if not attachment.size %} class="table-danger"{% endif %}>
19-
<td>
20-
<i class="mdi mdi-file-image-outline"></i>
21-
<a class="image-preview" href="{{ attachment.image.url }}" target="_blank">{{ attachment }}</a>
22-
</td>
23-
<td>{{ attachment.size|filesizeformat }}</td>
24-
<td>{{ attachment.created|annotated_date }}</td>
25-
<td class="text-end noprint">
26-
{% if perms.extras.change_imageattachment %}
27-
<a href="{% url 'extras:imageattachment_edit' pk=attachment.pk %}" class="btn btn-warning btn-sm lh-1" title="Edit Image">
28-
<i class="mdi mdi-pencil" aria-hidden="true"></i>
29-
</a>
30-
{% endif %}
31-
{% if perms.extras.delete_imageattachment %}
32-
<a href="{% url 'extras:imageattachment_delete' pk=attachment.pk %}" class="btn btn-danger btn-sm lh-1" title="Delete Image">
33-
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i>
34-
</a>
35-
{% endif %}
36-
</td>
37-
</tr>
38-
{% endfor %}
39-
</table>
40-
{% else %}
41-
<div class="text-muted">None</div>
42-
{% endif %}
43-
{% endwith %}
44-
</div>
7+
<div class="card-body htmx-container table-responsive"
8+
hx-get="{% url 'extras:imageattachment_list' %}?content_type_id={{ object|content_type_id }}&object_id={{ object.pk }}"
9+
hx-trigger="load"></div>
4510
{% if perms.extras.add_imageattachment %}
4611
<div class="card-footer text-end noprint">
4712
<a href="{% url 'extras:imageattachment_add' %}?content_type={{ object|content_type_id }}&object_id={{ object.pk }}" class="btn btn-primary btn-sm">

0 commit comments

Comments
 (0)