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

Add JournalEntry list view w/filtering

Jeremy Stretch 4 лет назад
Родитель
Сommit
8be4fbbce3

+ 20 - 10
netbox/extras/filters.py

@@ -119,22 +119,32 @@ class ImageAttachmentFilterSet(BaseFilterSet):
 
 
 class JournalEntryFilterSet(BaseFilterSet):
+    q = django_filters.CharFilter(
+        method='search',
+        label='Search',
+    )
+    created = django_filters.DateTimeFromToRangeFilter()
     assigned_object_type = ContentTypeFilter()
-    # created_by_id = django_filters.ModelMultipleChoiceFilter(
-    #     queryset=User.objects.all(),
-    #     label='User (ID)',
-    # )
-    # created_by = django_filters.ModelMultipleChoiceFilter(
-    #     field_name='user__username',
-    #     queryset=User.objects.all(),
-    #     to_field_name='username',
-    #     label='User (name)',
-    # )
+    created_by_id = django_filters.ModelMultipleChoiceFilter(
+        queryset=User.objects.all(),
+        label='User (ID)',
+    )
+    created_by = django_filters.ModelMultipleChoiceFilter(
+        field_name='created_by__username',
+        queryset=User.objects.all(),
+        to_field_name='username',
+        label='User (name)',
+    )
 
     class Meta:
         model = JournalEntry
         fields = ['id', 'assigned_object_type_id', 'assigned_object_id', 'created']
 
+    def search(self, queryset, name, value):
+        if not value.strip():
+            return queryset
+        return queryset.filter(comments__icontains=value)
+
 
 class TagFilterSet(BaseFilterSet):
     q = django_filters.CharFilter(

+ 34 - 0
netbox/extras/forms.py

@@ -386,6 +386,40 @@ class JournalEntryForm(BootstrapMixin, forms.ModelForm):
         }
 
 
+class JournalEntryFilterForm(BootstrapMixin, forms.Form):
+    model = JournalEntry
+    q = forms.CharField(
+        required=False,
+        label=_('Search')
+    )
+    created_after = forms.DateTimeField(
+        required=False,
+        label=_('After'),
+        widget=DateTimePicker()
+    )
+    created_before = forms.DateTimeField(
+        required=False,
+        label=_('Before'),
+        widget=DateTimePicker()
+    )
+    created_by_id = DynamicModelMultipleChoiceField(
+        queryset=User.objects.all(),
+        required=False,
+        label=_('User'),
+        widget=APISelectMultiple(
+            api_url='/api/users/users/',
+        )
+    )
+    assigned_object_type_id = DynamicModelMultipleChoiceField(
+        queryset=ContentType.objects.all(),
+        required=False,
+        label=_('Object Type'),
+        widget=APISelectMultiple(
+            api_url='/api/extras/content-types/',
+        )
+    )
+
+
 #
 # Change logging
 #

+ 1 - 0
netbox/extras/migrations/0058_journalentry.py

@@ -23,6 +23,7 @@ class Migration(migrations.Migration):
                 ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
             ],
             options={
+                'verbose_name_plural': 'journal entries',
                 'ordering': ('-created',),
             },
         ),

+ 1 - 0
netbox/extras/models/models.py

@@ -405,6 +405,7 @@ class JournalEntry(BigIDModel):
 
     class Meta:
         ordering = ('-created',)
+        verbose_name_plural = 'journal entries'
 
     def __str__(self):
         return f"{self.created}"

+ 25 - 0
netbox/extras/tables.py

@@ -98,7 +98,32 @@ class ObjectChangeTable(BaseTable):
         fields = ('time', 'user_name', 'action', 'changed_object_type', 'object_repr', 'request_id')
 
 
+class JournalEntryTable(BaseTable):
+    created = tables.DateTimeColumn(
+        format=settings.SHORT_DATETIME_FORMAT
+    )
+    assigned_object_type = tables.Column(
+        verbose_name='Object type'
+    )
+    assigned_object = tables.Column(
+        linkify=True,
+        orderable=False,
+        verbose_name='Object'
+    )
+    actions = ButtonsColumn(
+        model=JournalEntry,
+        buttons=('edit', 'delete')
+    )
+
+    class Meta(BaseTable.Meta):
+        model = JournalEntry
+        fields = ('created', 'created_by', 'assigned_object_type', 'assigned_object', 'comments', 'actions')
+
+
 class ObjectJournalTable(BaseTable):
+    """
+    Used for displaying a set of JournalEntries within the context of a single object.
+    """
     created = tables.DateTimeColumn(
         format=settings.SHORT_DATETIME_FORMAT
     )

+ 1 - 0
netbox/extras/urls.py

@@ -32,6 +32,7 @@ urlpatterns = [
     path('image-attachments/<int:pk>/delete/', views.ImageAttachmentDeleteView.as_view(), name='imageattachment_delete'),
 
     # Journal entries
+    path('journal-entries/', views.JournalEntryListView.as_view(), name='journalentry_list'),
     path('journal-entries/add/', views.JournalEntryEditView.as_view(), name='journalentry_add'),
     path('journal-entries/<int:pk>/edit/', views.JournalEntryEditView.as_view(), name='journalentry_edit'),
     path('journal-entries/<int:pk>/delete/', views.JournalEntryDeleteView.as_view(), name='journalentry_delete'),

+ 8 - 0
netbox/extras/views.py

@@ -286,6 +286,14 @@ class ImageAttachmentDeleteView(generic.ObjectDeleteView):
 # Journal entries
 #
 
+class JournalEntryListView(generic.ObjectListView):
+    queryset = JournalEntry.objects.all()
+    filterset = filters.JournalEntryFilterSet
+    filterset_form = forms.JournalEntryFilterForm
+    table = tables.JournalEntryTable
+    action_buttons = ('export',)
+
+
 class JournalEntryEditView(generic.ObjectEditView):
     queryset = JournalEntry.objects.all()
     model_form = forms.JournalEntryForm

+ 1 - 0
netbox/templates/extras/object_journal.html

@@ -27,4 +27,5 @@
         </div>
     {% endif %}
     {% include 'panel_table.html' %}
+    {% include 'inc/paginator.html' with paginator=table.paginator page=table.page %}
 {% endblock %}

+ 3 - 0
netbox/templates/inc/nav_menu.html

@@ -520,6 +520,9 @@
                     <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Other <span class="caret"></span></a>
                     <ul class="dropdown-menu">
                         <li class="dropdown-header">Logging</li>
+                        <li{% if not perms.extras.view_journalentry %} class="disabled"{% endif %}>
+                            <a href="{% url 'extras:journalentry_list' %}">Journal Entries</a>
+                        </li>
                         <li{% if not perms.extras.view_objectchange %} class="disabled"{% endif %}>
                             <a href="{% url 'extras:objectchange_list' %}">Change Log</a>
                         </li>