Add data file UI view

This commit is contained in:
jeremystretch 2023-01-27 14:39:36 -05:00
parent b38b4e11a6
commit 7ae6d821fa
8 changed files with 120 additions and 10 deletions

View File

@ -3,6 +3,7 @@ from django.utils.translation import gettext as _
import django_filters import django_filters
from netbox.filtersets import ChangeLoggedModelFilterSet
from .models import * from .models import *
__all__ = ( __all__ = (
@ -11,7 +12,7 @@ __all__ = (
) )
class DataSourceFilterSet(django_filters.FilterSet): class DataSourceFilterSet(ChangeLoggedModelFilterSet):
class Meta: class Meta:
model = DataSource model = DataSource
@ -27,11 +28,14 @@ class DataSourceFilterSet(django_filters.FilterSet):
class DataFileFilterSet(django_filters.FilterSet): class DataFileFilterSet(django_filters.FilterSet):
datasource_id = django_filters.ModelMultipleChoiceFilter( q = django_filters.CharFilter(
method='search'
)
source_id = django_filters.ModelMultipleChoiceFilter(
queryset=DataSource.objects.all(), queryset=DataSource.objects.all(),
label=_('Data source (ID)'), label=_('Data source (ID)'),
) )
datasource = django_filters.ModelMultipleChoiceFilter( source = django_filters.ModelMultipleChoiceFilter(
field_name='source__name', field_name='source__name',
queryset=DataSource.objects.all(), queryset=DataSource.objects.all(),
to_field_name='name', to_field_name='name',

View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext as _
from core.choices import * from core.choices import *
from core.models import * from core.models import *
@ -38,11 +39,12 @@ class DataFileFilterForm(NetBoxModelFilterSetForm):
model = DataFile model = DataFile
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('File', ('datasource_id',)), ('File', ('source_id',)),
) )
datasource_id = DynamicModelMultipleChoiceField( source_id = DynamicModelMultipleChoiceField(
queryset=DataSource.objects.all(), queryset=DataSource.objects.all(),
required=False required=False,
label=_('Data source')
) )
type = MultipleChoiceField( type = MultipleChoiceField(
choices=DataSourceTypeChoices, choices=DataSourceTypeChoices,

View File

@ -306,6 +306,16 @@ class DataFile(models.Model):
def __str__(self): def __str__(self):
return self.path return self.path
def get_absolute_url(self):
return reverse('core:datafile', args=[self.pk])
@property
def data_as_string(self):
try:
return self.data.tobytes().decode('utf-8')
except UnicodeDecodeError:
return None
def refresh_from_disk(self, source_root): def refresh_from_disk(self, source_root):
""" """
Update instance attributes from the file on disk. Returns True if any attribute Update instance attributes from the file on disk. Returns True if any attribute

View File

@ -33,6 +33,9 @@ class DataFileTable(NetBoxTable):
source = tables.Column( source = tables.Column(
linkify=True linkify=True
) )
path = tables.Column(
linkify=True
)
last_updated = columns.DateTimeColumn() last_updated = columns.DateTimeColumn()
actions = None actions = None

View File

@ -16,5 +16,6 @@ urlpatterns = (
# Data files # Data files
path('data-files/', views.DataFileListView.as_view(), name='datafile_list'), path('data-files/', views.DataFileListView.as_view(), name='datafile_list'),
path('data-files/<int:pk>/', include(get_model_urls('core', 'datafile'))),
) )

View File

@ -1,14 +1,11 @@
from django.contrib import messages from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from extras.models import JobResult
from netbox.views import generic from netbox.views import generic
from netbox.views.generic.base import BaseObjectView from netbox.views.generic.base import BaseObjectView
from utilities.utils import count_related from utilities.utils import count_related
from utilities.views import register_model_view from utilities.views import register_model_view
from . import filtersets, forms, jobs, tables from . import filtersets, forms, tables
from .choices import *
from .models import * from .models import *
@ -29,6 +26,15 @@ class DataSourceListView(generic.ObjectListView):
class DataSourceView(generic.ObjectView): class DataSourceView(generic.ObjectView):
queryset = DataSource.objects.all() queryset = DataSource.objects.all()
def get_extra_context(self, request, instance):
related_models = (
(DataFile.objects.restrict(request.user, 'view').filter(source=instance), 'source_id'),
)
return {
'related_models': related_models,
}
@register_model_view(DataSource, 'sync') @register_model_view(DataSource, 'sync')
class DataSourceSyncView(BaseObjectView): class DataSourceSyncView(BaseObjectView):
@ -94,3 +100,8 @@ class DataFileListView(generic.ObjectListView):
filterset_form = forms.DataFileFilterForm filterset_form = forms.DataFileFilterForm
table = tables.DataFileTable table = tables.DataFileTable
actions = ('edit',) actions = ('edit',)
@register_model_view(DataFile)
class DataFileView(generic.ObjectView):
queryset = DataFile.objects.all()

View File

@ -0,0 +1,77 @@
{% extends 'generic/object.html' %}
{% load custom_links %}
{% load helpers %}
{% load plugins %}
{% block breadcrumbs %}
{{ block.super }}
<li class="breadcrumb-item"><a href="{% url 'core:datafile_list' %}?source_id={{ object.source.pk }}">{{ object.source }}</a></li>
{% endblock %}
{% block controls %}
{# Clone/Edit/Delete Buttons #}
<div class="controls">
<div class="control-group">
{% plugin_buttons object %}
</div>
<div class="control-group">
{% custom_links object %}
</div>
</div>
{% endblock controls %}
{% block content %}
<div class="row mb-3">
<div class="col">
<div class="card">
<h5 class="card-header">Data File</h5>
<div class="card-body">
<table class="table table-hover attr-table">
<tr>
<th scope="row">Source</th>
<td><a href="{{ object.source.get_absolute_url }}">{{ object.source }}</a></td>
</tr>
<tr>
<th scope="row">Path</th>
<td>
<span class="font-monospace" id="datafile_path">{{ object.path }}</span>
<a class="btn btn-sm btn-primary copy-token" data-clipboard-target="#datafile_path" title="Copy to clipboard">
<i class="mdi mdi-content-copy"></i>
</a>
</td>
</tr>
<tr>
<th scope="row">Last Updated</th>
<td>{{ object.last_updated }}</td>
</tr>
<tr>
<th scope="row">Size</th>
<td>{{ object.size }} byte{{ object.size|pluralize }}</td>
</tr>
<tr>
<th scope="row">SHA256 Hash</th>
<td>
<span class="font-monospace" id="datafile_hash">{{ object.hash }}</span>
<a class="btn btn-sm btn-primary copy-token" data-clipboard-target="#datafile_hash" title="Copy to clipboard">
<i class="mdi mdi-content-copy"></i>
</a>
</td>
</tr>
</table>
</div>
</div>
<div class="card">
<h5 class="card-header">Content</h5>
<div class="card-body">
<pre>{{ object.data_as_string }}</pre>
</div>
</div>
{% plugin_left_page object %}
</div>
</div>
<div class="row mb-3">
<div class="col col-md-12">
{% plugin_full_width_page object %}
</div>
</div>
{% endblock %}

View File

@ -95,6 +95,8 @@
</tr> </tr>
</table> </table>
</div> </div>
</div>
{% include 'inc/panels/related_objects.html' %}
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>