wip installation model
This commit is contained in:
@@ -5,7 +5,7 @@ from netbox.api.serializers import PrimaryModelSerializer, OrganizationalModelSe
|
|||||||
# NestedRecordSerializer,
|
# NestedRecordSerializer,
|
||||||
# NestedNameServerSerializer,
|
# NestedNameServerSerializer,
|
||||||
# )
|
# )
|
||||||
from netbox_slm.models import SoftwareProduct
|
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion
|
||||||
|
|
||||||
|
|
||||||
class SoftwareProductSerializer(PrimaryModelSerializer):
|
class SoftwareProductSerializer(PrimaryModelSerializer):
|
||||||
@@ -22,3 +22,19 @@ class SoftwareProductSerializer(PrimaryModelSerializer):
|
|||||||
|
|
||||||
def get_display(self, obj):
|
def get_display(self, obj):
|
||||||
return obj.name
|
return obj.name
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductVersionSerializer(PrimaryModelSerializer):
|
||||||
|
display = serializers.SerializerMethodField()
|
||||||
|
url = serializers.HyperlinkedIdentityField(
|
||||||
|
view_name="plugins-api:netbox_slm-api:softwareproductversion-detail"
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = SoftwareProductVersion
|
||||||
|
fields = [
|
||||||
|
'id', 'display', 'url', 'name', 'software_product', 'tags', 'custom_field_data', 'created', 'last_updated',
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_display(self, obj):
|
||||||
|
return obj.name
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
from netbox.api import OrderedDefaultRouter
|
from netbox.api import OrderedDefaultRouter
|
||||||
from netbox_slm.api.views import (
|
from netbox_slm.api.views import (
|
||||||
NetboxSLMRootView,
|
NetboxSLMRootView,
|
||||||
SoftwareProductViewSet
|
SoftwareProductViewSet,
|
||||||
|
SoftwareProductVersionViewSet,
|
||||||
)
|
)
|
||||||
|
|
||||||
router = OrderedDefaultRouter()
|
router = OrderedDefaultRouter()
|
||||||
router.APIRootView = NetboxSLMRootView
|
router.APIRootView = NetboxSLMRootView
|
||||||
|
|
||||||
router.register("softwareproducts", SoftwareProductViewSet)
|
router.register("softwareproducts", SoftwareProductViewSet)
|
||||||
|
router.register("softwareproductversions", SoftwareProductVersionViewSet)
|
||||||
urlpatterns = router.urls
|
urlpatterns = router.urls
|
||||||
@@ -4,9 +4,9 @@ from rest_framework.response import Response
|
|||||||
from rest_framework.routers import APIRootView
|
from rest_framework.routers import APIRootView
|
||||||
|
|
||||||
from extras.api.views import CustomFieldModelViewSet
|
from extras.api.views import CustomFieldModelViewSet
|
||||||
from netbox_slm.api.serializers import SoftwareProductSerializer
|
from netbox_slm.api.serializers import SoftwareProductSerializer, SoftwareProductVersionSerializer
|
||||||
from netbox_slm.filters import SoftwareProductFilter
|
from netbox_slm.filters import SoftwareProductFilter, SoftwareProductVersionFilter
|
||||||
from netbox_slm.models import SoftwareProduct
|
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion
|
||||||
|
|
||||||
|
|
||||||
class NetboxSLMRootView(APIRootView):
|
class NetboxSLMRootView(APIRootView):
|
||||||
@@ -29,4 +29,16 @@ class SoftwareProductViewSet(CustomFieldModelViewSet):
|
|||||||
# serializer = RecordSerializer(records, many=True, context={"request": request})
|
# serializer = RecordSerializer(records, many=True, context={"request": request})
|
||||||
# return Response(serializer.data)
|
# return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductVersionViewSet(CustomFieldModelViewSet):
|
||||||
|
queryset = SoftwareProductVersion.objects.all()
|
||||||
|
serializer_class = SoftwareProductVersionSerializer
|
||||||
|
filterset_class = SoftwareProductVersionFilter
|
||||||
|
|
||||||
|
# @action(detail=True, methods=["get"])
|
||||||
|
# def records(self, request, pk=None):
|
||||||
|
# records = Record.objects.filter(zone=pk)
|
||||||
|
# serializer = RecordSerializer(records, many=True, context={"request": request})
|
||||||
|
# return Response(serializer.data)
|
||||||
|
|
||||||
# for reference: https://github.com/auroraresearchlab/netbox-dns/blob/main/netbox_dns/api/views.py
|
# for reference: https://github.com/auroraresearchlab/netbox-dns/blob/main/netbox_dns/api/views.py
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
import django_filters
|
import django_filters
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
from extras.filters import TagFilter
|
from extras.filters import TagFilter
|
||||||
from netbox.filtersets import PrimaryModelFilterSet
|
from netbox.filtersets import PrimaryModelFilterSet
|
||||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion
|
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||||
|
from utilities.forms import DynamicModelMultipleChoiceField
|
||||||
|
|
||||||
|
|
||||||
class SoftwareProductFilter(PrimaryModelFilterSet):
|
class BaseFilter(PrimaryModelFilterSet):
|
||||||
"""Filter capabilities for SoftwareProduct instances."""
|
|
||||||
|
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
method="search",
|
method="search",
|
||||||
label="Search",
|
label="Search",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductFilter(BaseFilter):
|
||||||
|
"""Filter capabilities for SoftwareProduct instances."""
|
||||||
|
|
||||||
name = django_filters.CharFilter(
|
name = django_filters.CharFilter(
|
||||||
lookup_expr="icontains",
|
lookup_expr="icontains",
|
||||||
)
|
)
|
||||||
@@ -29,7 +34,35 @@ class SoftwareProductFilter(PrimaryModelFilterSet):
|
|||||||
return queryset.filter(qs_filter)
|
return queryset.filter(qs_filter)
|
||||||
|
|
||||||
|
|
||||||
class SoftwareProductVersionFilter(SoftwareProductFilter):
|
class SoftwareProductVersionFilter(BaseFilter):
|
||||||
|
name = django_filters.CharFilter(
|
||||||
|
lookup_expr="icontains",
|
||||||
|
)
|
||||||
|
# software_product_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
# queryset=SoftwareProduct.objects.all(),
|
||||||
|
# label='SoftwareProduct (ID)',
|
||||||
|
# )
|
||||||
|
# software_product = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
# field_name='software_product__name',
|
||||||
|
# queryset=SoftwareProduct.objects.all(),
|
||||||
|
# to_field_name='name',
|
||||||
|
# label='SoftwareProduct (name)',
|
||||||
|
# )
|
||||||
|
# tag = TagFilter()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SoftwareProductVersion
|
model = SoftwareProductVersion
|
||||||
fields = ("name",) # "tag")
|
fields = ("name", "software_product") # "tag")
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
"""Perform the filtered search."""
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
qs_filter = Q(name__icontains=value) # | Q(status__icontains=value)
|
||||||
|
return queryset.filter(qs_filter)
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationFilter(BaseFilter):
|
||||||
|
class Meta:
|
||||||
|
model = SoftwareProductInstallation
|
||||||
|
fields = tuple() # "tag")
|
||||||
|
|||||||
+73
-2
@@ -1,5 +1,6 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
from extras.forms import (
|
from extras.forms import (
|
||||||
CustomFieldModelForm,
|
CustomFieldModelForm,
|
||||||
CustomFieldModelCSVForm,
|
CustomFieldModelCSVForm,
|
||||||
@@ -7,8 +8,8 @@ from extras.forms import (
|
|||||||
CustomFieldModelBulkEditForm,
|
CustomFieldModelBulkEditForm,
|
||||||
CustomFieldModelFilterForm,
|
CustomFieldModelFilterForm,
|
||||||
)
|
)
|
||||||
from dcim.models import Manufacturer
|
from dcim.models import Manufacturer, Device
|
||||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion
|
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||||
from utilities.forms import (
|
from utilities.forms import (
|
||||||
BootstrapMixin, DynamicModelChoiceField, APISelect, DynamicModelMultipleChoiceField
|
BootstrapMixin, DynamicModelChoiceField, APISelect, DynamicModelMultipleChoiceField
|
||||||
)
|
)
|
||||||
@@ -120,3 +121,73 @@ class SoftwareProductVersionBulkEditForm(BootstrapMixin, AddRemoveTagsForm, Cust
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
nullable_fields = []
|
nullable_fields = []
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationForm(BootstrapMixin, CustomFieldModelForm):
|
||||||
|
"""Form for creating a new SoftwareProductInstallation object."""
|
||||||
|
|
||||||
|
device = DynamicModelChoiceField(
|
||||||
|
queryset=Device.objects.all(),
|
||||||
|
required=False,
|
||||||
|
# initial_params={
|
||||||
|
# 'device_types': 'device_type'
|
||||||
|
# }
|
||||||
|
)
|
||||||
|
software_product = DynamicModelChoiceField(
|
||||||
|
queryset=SoftwareProduct.objects.all(),
|
||||||
|
required=False,
|
||||||
|
widget=APISelect(
|
||||||
|
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproduct-list")}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
version = DynamicModelChoiceField(
|
||||||
|
queryset=SoftwareProductVersion.objects.all(),
|
||||||
|
required=False,
|
||||||
|
widget=APISelect(
|
||||||
|
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproductversion-list")}
|
||||||
|
),
|
||||||
|
query_params={
|
||||||
|
'software_product': '$software_product',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# todo need version and device ?
|
||||||
|
|
||||||
|
# tags = DynamicModelMultipleChoiceField(
|
||||||
|
# queryset=Tag.objects.all(),
|
||||||
|
# required=False,
|
||||||
|
# )
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = SoftwareProductInstallation
|
||||||
|
fields = ("device", "software_product", "version",) # "tags")
|
||||||
|
|
||||||
|
# def clean(self):
|
||||||
|
# import pdb;pdb.set_trace()
|
||||||
|
# return super(SoftwareProductInstallationForm, self).clean()
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
|
"""Form for filtering SoftwareProductInstallation instances."""
|
||||||
|
|
||||||
|
model = SoftwareProductInstallation
|
||||||
|
|
||||||
|
q = forms.CharField(required=False, label="Search")
|
||||||
|
|
||||||
|
# tag = TagFilterField(SoftwareProduct)
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationCSVForm(CustomFieldModelCSVForm):
|
||||||
|
class Meta:
|
||||||
|
model = SoftwareProductInstallation
|
||||||
|
fields = tuple()
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
||||||
|
pk = forms.ModelMultipleChoiceField(
|
||||||
|
queryset=SoftwareProductInstallation.objects.all(),
|
||||||
|
widget=forms.MultipleHiddenInput(),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
nullable_fields = []
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Generated by Django 3.2.8 on 2021-12-08 12:10
|
||||||
|
|
||||||
|
import django.core.serializers.json
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import taggit.managers
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('extras', '0062_clear_secrets_changelog'),
|
||||||
|
('dcim', '0133_port_colors'),
|
||||||
|
('netbox_slm', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SoftwareProductInstallation',
|
||||||
|
fields=[
|
||||||
|
('created', models.DateField(auto_now_add=True, null=True)),
|
||||||
|
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
||||||
|
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
|
||||||
|
('id', models.BigAutoField(primary_key=True, serialize=False)),
|
||||||
|
('device', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='softwareproduct_installations', to='dcim.device')),
|
||||||
|
('software_product', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='software_products', to='netbox_slm.softwareproduct')),
|
||||||
|
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
|
||||||
|
('version', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='softwareproduct_versions', to='netbox_slm.softwareproductversion')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -44,3 +44,35 @@ class SoftwareProductVersion(PrimaryModel):
|
|||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse("plugins:netbox_slm:softwareproductversion", kwargs={"pk": self.pk})
|
return reverse("plugins:netbox_slm:softwareproductversion", kwargs={"pk": self.pk})
|
||||||
|
|
||||||
|
|
||||||
|
# @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
|
||||||
|
class SoftwareProductInstallation(PrimaryModel):
|
||||||
|
device = models.ForeignKey(
|
||||||
|
to='dcim.Device',
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
related_name='softwareproduct_installations'
|
||||||
|
)
|
||||||
|
# virtualmachine = models.ForeignKey(
|
||||||
|
# to='virtualization.VirtualMachine',
|
||||||
|
# on_delete=models.PROTECT,
|
||||||
|
# related_name='softwareproduct_installations'
|
||||||
|
# )
|
||||||
|
software_product = models.ForeignKey(
|
||||||
|
to='netbox_slm.SoftwareProduct',
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
related_name='software_products'
|
||||||
|
)
|
||||||
|
version = models.ForeignKey(
|
||||||
|
to='netbox_slm.SoftwareProductVersion',
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
related_name='softwareproduct_versions'
|
||||||
|
)
|
||||||
|
|
||||||
|
objects = RestrictedQuerySet.as_manager()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.pk}"
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse("plugins:netbox_slm:softwareproductinstallation", kwargs={"pk": self.pk})
|
||||||
|
|||||||
@@ -42,4 +42,24 @@ menu_items = (
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
PluginMenuItem(
|
||||||
|
link='plugins:netbox_slm:softwareproductinstallation_list',
|
||||||
|
link_text='Installations',
|
||||||
|
buttons=(
|
||||||
|
PluginMenuButton(
|
||||||
|
"plugins:netbox_slm:softwareproductinstallation_add",
|
||||||
|
"Add",
|
||||||
|
"mdi mdi-plus-thick",
|
||||||
|
ButtonColorChoices.GREEN,
|
||||||
|
permissions=["netbox_slm.add_softwareproductinstallation"],
|
||||||
|
),
|
||||||
|
PluginMenuButton(
|
||||||
|
"plugins:netbox_slm:softwareproductinstallation_import",
|
||||||
|
"Import",
|
||||||
|
"mdi mdi-upload",
|
||||||
|
ButtonColorChoices.CYAN,
|
||||||
|
permissions=["netbox_slm.add_softwareproductinstallation"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django_tables2.utils import Accessor
|
from django_tables2.utils import Accessor
|
||||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion
|
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||||
from utilities.tables import BaseTable, ChoiceFieldColumn, ToggleColumn
|
from utilities.tables import BaseTable, ChoiceFieldColumn, ToggleColumn
|
||||||
|
|
||||||
|
|
||||||
@@ -68,3 +68,44 @@ class SoftwareProductVersionTable(BaseTable):
|
|||||||
"manufacturer",
|
"manufacturer",
|
||||||
# "tags",
|
# "tags",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationTable(BaseTable):
|
||||||
|
"""Table for displaying SoftwareProductInstallation objects."""
|
||||||
|
|
||||||
|
pk = ToggleColumn()
|
||||||
|
name = tables.LinkColumn()
|
||||||
|
device = tables.Column(
|
||||||
|
accessor=Accessor('device'),
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
software_product = tables.Column(
|
||||||
|
accessor=Accessor('software_product'),
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
version = tables.Column(
|
||||||
|
accessor=Accessor('version'),
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
|
||||||
|
# tags = TagColumn(
|
||||||
|
# url_name="plugins:netbox_dns:zone_list",
|
||||||
|
# )
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = SoftwareProductInstallation
|
||||||
|
fields = (
|
||||||
|
"pk",
|
||||||
|
"name",
|
||||||
|
"device",
|
||||||
|
"software_product",
|
||||||
|
"version",
|
||||||
|
# "tags",
|
||||||
|
)
|
||||||
|
default_columns = (
|
||||||
|
"pk",
|
||||||
|
"device",
|
||||||
|
"software_product",
|
||||||
|
"version",
|
||||||
|
# "tags",
|
||||||
|
)
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
{% extends 'netbox_slm/object.html' %}
|
||||||
|
{% load helpers %}
|
||||||
|
{% load plugins %}
|
||||||
|
{% load render_table from django_tables2 %}
|
||||||
|
{% load view_helpers %}
|
||||||
|
{% load perms %}
|
||||||
|
|
||||||
|
{% block extra_controls %}
|
||||||
|
{{ block.super }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-md-6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
Software Product
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-hover attr-table">
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Installation</th>
|
||||||
|
<td>{{ object }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">bla</th>
|
||||||
|
<td>
|
||||||
|
<!-- {% for version in object.softwareproduct_versions.all %}-->
|
||||||
|
<!-- <a href="{% url 'plugins:netbox_slm:softwareproductversion' pk=version.pk %}">-->
|
||||||
|
<!-- <span class="badge" style="color: #ffffff; background-color: #9e9e9e">{{ version }}</span>-->
|
||||||
|
<!-- </a>-->
|
||||||
|
<!-- {% endfor %}-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% include 'inc/custom_fields_panel.html' %}
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-6">
|
||||||
|
{% include 'extras/inc/tags_panel.html' with tags=object.tags.all url='plugins:netbox_slm:softwareproduct_list' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--<div class="row">-->
|
||||||
|
<!-- <div class="col col-md-12">-->
|
||||||
|
<!-- <div class="card">-->
|
||||||
|
<!-- <h5 class="card-header">Records</h5>-->
|
||||||
|
<!-- <div class="card-body">-->
|
||||||
|
<!-- <table class="table table-hover attr-table table-striped">-->
|
||||||
|
<!-- <thead>-->
|
||||||
|
<!-- <tr>-->
|
||||||
|
<!-- <th scope="col">TYPE</th>-->
|
||||||
|
<!-- <th scope="col">NAME</th>-->
|
||||||
|
<!-- <th scope="col">VALUE</th>-->
|
||||||
|
<!-- <th scope="col">TTL</th>-->
|
||||||
|
<!-- <th scope="col">Actions</th>-->
|
||||||
|
<!-- </tr>-->
|
||||||
|
<!-- </thead>-->
|
||||||
|
<!-- <tbody>-->
|
||||||
|
<!-- {% for record in records %}-->
|
||||||
|
<!-- <tr>-->
|
||||||
|
<!-- <td>{{ record.type }}</td>-->
|
||||||
|
<!-- <td>{{ record.name|truncatechars:32 }}</td>-->
|
||||||
|
<!-- <td>{{ record.value|truncatechars:64 }}</td>-->
|
||||||
|
<!-- <td>{{ record.ttl }}</td>-->
|
||||||
|
<!-- <td class="noprint text-end text-nowrap">-->
|
||||||
|
<!-- {% if request.user|can_change:object %}-->
|
||||||
|
<!-- {% plugin_edit_button record %}-->
|
||||||
|
<!-- {% endif %}-->
|
||||||
|
<!-- {% if request.user|can_delete:object %}-->
|
||||||
|
<!-- {% plugin_delete_button record %}-->
|
||||||
|
<!-- {% endif %}-->
|
||||||
|
<!-- </td>-->
|
||||||
|
<!-- </tr>-->
|
||||||
|
<!-- {% endfor %}-->
|
||||||
|
<!-- </tbody>-->
|
||||||
|
<!-- </table>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!--</div>-->
|
||||||
|
{% endblock %}
|
||||||
+17
-1
@@ -1,7 +1,7 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
from extras.views import ObjectChangeLogView
|
from extras.views import ObjectChangeLogView
|
||||||
from netbox_slm import views
|
from netbox_slm import views
|
||||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion
|
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# Software Products
|
# Software Products
|
||||||
@@ -35,4 +35,20 @@ urlpatterns = [
|
|||||||
name="softwareproductversion_changelog",
|
name="softwareproductversion_changelog",
|
||||||
kwargs={"model": SoftwareProductVersion},
|
kwargs={"model": SoftwareProductVersion},
|
||||||
),
|
),
|
||||||
|
|
||||||
|
# Software Product Versions
|
||||||
|
path("installations/", views.SoftwareProductInstallationListView.as_view(), name='softwareproductinstallation_list'),
|
||||||
|
path("installations/add/", views.SoftwareProductInstallationEditView.as_view(), name='softwareproductinstallation_add'),
|
||||||
|
path("installations/import/", views.SoftwareProductInstallationBulkImportView.as_view(), name="softwareproductinstallation_import"),
|
||||||
|
path("installations/edit/", views.SoftwareProductInstallationBulkEditView.as_view(), name="softwareproductinstallation_bulk_edit"),
|
||||||
|
path("installations/delete/", views.SoftwareProductInstallationBulkDeleteView.as_view(), name="softwareproductinstallation_bulk_delete"),
|
||||||
|
path("installations/<int:pk>/", views.SoftwareProductInstallationView.as_view(), name="softwareproductinstallation"),
|
||||||
|
path("installations/<int:pk>/delete/", views.SoftwareProductInstallationDeleteView.as_view(), name="softwareproductinstallation_delete"),
|
||||||
|
path("installations/<int:pk>/edit/", views.SoftwareProductInstallationEditView.as_view(), name="softwareproductinstallation_edit"),
|
||||||
|
path(
|
||||||
|
"installations/<int:pk>/changelog/",
|
||||||
|
ObjectChangeLogView.as_view(),
|
||||||
|
name="softwareproductinstallation_changelog",
|
||||||
|
kwargs={"model": SoftwareProductInstallation},
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
+56
-4
@@ -1,14 +1,15 @@
|
|||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from netbox_slm.filters import SoftwareProductFilter, SoftwareProductVersionFilter
|
from netbox_slm.filters import SoftwareProductFilter, SoftwareProductVersionFilter, SoftwareProductInstallationFilter
|
||||||
from netbox_slm.forms import (
|
from netbox_slm.forms import (
|
||||||
SoftwareProductForm, SoftwareProductFilterForm, SoftwareProductCSVForm, SoftwareProductBulkEditForm,
|
SoftwareProductForm, SoftwareProductFilterForm, SoftwareProductCSVForm, SoftwareProductBulkEditForm,
|
||||||
SoftwareProductVersionForm, SoftwareProductVersionFilterForm, SoftwareProductVersionCSVForm,
|
SoftwareProductVersionForm, SoftwareProductVersionFilterForm, SoftwareProductVersionCSVForm,
|
||||||
SoftwareProductVersionBulkEditForm
|
SoftwareProductVersionBulkEditForm, SoftwareProductInstallationForm, SoftwareProductInstallationFilterForm,
|
||||||
|
SoftwareProductInstallationCSVForm, SoftwareProductInstallationBulkEditForm
|
||||||
)
|
)
|
||||||
from netbox_slm.models import (
|
from netbox_slm.models import (
|
||||||
SoftwareProduct, SoftwareProductVersion
|
SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||||
)
|
)
|
||||||
from netbox_slm.tables import SoftwareProductTable, SoftwareProductVersionTable
|
from netbox_slm.tables import SoftwareProductTable, SoftwareProductVersionTable, SoftwareProductInstallationTable
|
||||||
|
|
||||||
|
|
||||||
class SoftwareProductListView(generic.ObjectListView):
|
class SoftwareProductListView(generic.ObjectListView):
|
||||||
@@ -111,3 +112,54 @@ class SoftwareProductVersionBulkEditView(generic.BulkEditView):
|
|||||||
class SoftwareProductVersionBulkDeleteView(generic.BulkDeleteView):
|
class SoftwareProductVersionBulkDeleteView(generic.BulkDeleteView):
|
||||||
queryset = SoftwareProductVersion.objects.all()
|
queryset = SoftwareProductVersion.objects.all()
|
||||||
table = SoftwareProductVersionTable
|
table = SoftwareProductVersionTable
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationListView(generic.ObjectListView):
|
||||||
|
"""View for listing all existing SoftwareProductInstallations."""
|
||||||
|
|
||||||
|
queryset = SoftwareProductInstallation.objects.all()
|
||||||
|
filterset = SoftwareProductInstallationFilter
|
||||||
|
filterset_form = SoftwareProductInstallationFilterForm
|
||||||
|
table = SoftwareProductInstallationTable
|
||||||
|
template_name = "netbox_slm/object_list.html"
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationView(generic.ObjectView):
|
||||||
|
"""Display SoftwareProductInstallation details"""
|
||||||
|
|
||||||
|
queryset = SoftwareProductVersion.objects.all()
|
||||||
|
|
||||||
|
# def get_extra_context(self, request, instance):
|
||||||
|
# records = instance.record_set.all()
|
||||||
|
# return {"records": records}
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationEditView(generic.ObjectEditView):
|
||||||
|
"""View for editing and creating a SoftwareProductInstallation instance."""
|
||||||
|
|
||||||
|
queryset = SoftwareProductInstallation.objects.all()
|
||||||
|
model_form = SoftwareProductInstallationForm
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationDeleteView(generic.ObjectDeleteView):
|
||||||
|
"""View for deleting a SoftwareProductInstallation instance"""
|
||||||
|
|
||||||
|
queryset = SoftwareProductInstallation.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationBulkImportView(generic.BulkImportView):
|
||||||
|
queryset = SoftwareProductInstallation.objects.all()
|
||||||
|
model_form = SoftwareProductInstallationCSVForm
|
||||||
|
table = SoftwareProductInstallationTable
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationBulkEditView(generic.BulkEditView):
|
||||||
|
queryset = SoftwareProductInstallation.objects.all()
|
||||||
|
filterset = SoftwareProductInstallationFilter
|
||||||
|
table = SoftwareProductInstallationTable
|
||||||
|
form = SoftwareProductInstallationBulkEditForm
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareProductInstallationBulkDeleteView(generic.BulkDeleteView):
|
||||||
|
queryset = SoftwareProductInstallation.objects.all()
|
||||||
|
table = SoftwareProductInstallationTable
|
||||||
|
|||||||
Reference in New Issue
Block a user