From 24f9f192dfa6f516b78b8b19597301cd925d78cb Mon Sep 17 00:00:00 2001 From: Andrew Dickinson Date: Sun, 2 Jun 2024 16:23:54 -0400 Subject: [PATCH] Integrate django-import-export --- pyproject.toml | 1 + src/meshapi/admin/building.py | 3 ++- src/meshapi/admin/device.py | 3 ++- src/meshapi/admin/install.py | 16 +++++++++++++++- src/meshapi/admin/link.py | 3 ++- src/meshapi/admin/member.py | 3 ++- src/meshapi/admin/node.py | 16 +++++++++++++++- src/meshapi/admin/sector.py | 3 ++- src/meshdb/settings.py | 4 ++++ 9 files changed, 45 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bdda432d3..10a922c84 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ dependencies = [ # FIXME: Go back to PyPI when https://github.com/jazzband/django-dbbackup/pull/515 or https://github.com/jazzband/django-dbbackup/pull/511 is merged "django-dbbackup@git+https://github.com/willnilges/django-dbbackup.git@62048411ff5beac4beac1578f686824214f1f33a", "django-storages==1.14.*", + "django-import-export==4.0.*", "boto3==1.34.*", "six==1.16.0", ] diff --git a/src/meshapi/admin/building.py b/src/meshapi/admin/building.py index 02585f93b..ffedf3018 100644 --- a/src/meshapi/admin/building.py +++ b/src/meshapi/admin/building.py @@ -1,6 +1,7 @@ from django.contrib import admin from django.contrib.admin.options import forms from django.utils.safestring import mark_safe +from import_export.admin import ExportActionMixin, ImportExportModelAdmin from meshapi.admin.inlines import InstallInline from meshapi.models import Building @@ -45,7 +46,7 @@ class Meta: @admin.register(Building) -class BuildingAdmin(admin.ModelAdmin): +class BuildingAdmin(ImportExportModelAdmin, ExportActionMixin): form = BuildingAdminForm list_display = ["__str__", "street_address", "primary_node"] search_fields = [ diff --git a/src/meshapi/admin/device.py b/src/meshapi/admin/device.py index 980873636..cfe6bfd93 100644 --- a/src/meshapi/admin/device.py +++ b/src/meshapi/admin/device.py @@ -1,5 +1,6 @@ from django.contrib import admin from django.contrib.admin.options import forms +from import_export.admin import ExportActionMixin, ImportExportModelAdmin from meshapi.admin.admin import device_fieldsets from meshapi.admin.inlines import DeviceLinkInline @@ -17,7 +18,7 @@ class Meta: @admin.register(Device) -class DeviceAdmin(admin.ModelAdmin): +class DeviceAdmin(ImportExportModelAdmin, ExportActionMixin): form = DeviceAdminForm search_fields = ["name__icontains", "model__icontains", "ssid__icontains", "notes__icontains"] list_display = [ diff --git a/src/meshapi/admin/install.py b/src/meshapi/admin/install.py index 5dbef951e..4c6ef97df 100644 --- a/src/meshapi/admin/install.py +++ b/src/meshapi/admin/install.py @@ -1,9 +1,22 @@ from django.contrib import admin from django.contrib.admin.options import forms +from import_export import resources +from import_export.admin import ExportActionMixin, ImportExportModelAdmin from meshapi.models import Install +class InstallImportExportResource(resources.ModelResource): + def before_import(self, dataset, **kwargs): + if "install_number" not in dataset.headers: + dataset.headers.append("install_number") + super().before_import(dataset, **kwargs) + + class Meta: + model = Install + import_id_fields = ("install_number",) + + class InstallAdminForm(forms.ModelForm): class Meta: model = Install @@ -14,8 +27,9 @@ class Meta: @admin.register(Install) -class InstallAdmin(admin.ModelAdmin): +class InstallAdmin(ImportExportModelAdmin, ExportActionMixin): form = InstallAdminForm + resource_classes = [InstallImportExportResource] list_filter = [ ("node", admin.EmptyFieldListFilter), "status", diff --git a/src/meshapi/admin/link.py b/src/meshapi/admin/link.py index 5ec522bdc..0208b591a 100644 --- a/src/meshapi/admin/link.py +++ b/src/meshapi/admin/link.py @@ -1,5 +1,6 @@ from django.contrib import admin from django.contrib.admin.options import forms +from import_export.admin import ExportActionMixin, ImportExportModelAdmin from meshapi.models import Link @@ -14,7 +15,7 @@ class Meta: @admin.register(Link) -class LinkAdmin(admin.ModelAdmin): +class LinkAdmin(ImportExportModelAdmin, ExportActionMixin): form = LinkAdminForm search_fields = [ "from_device__node__name__icontains", diff --git a/src/meshapi/admin/member.py b/src/meshapi/admin/member.py index 2b0641fb2..36ab2b1b4 100644 --- a/src/meshapi/admin/member.py +++ b/src/meshapi/admin/member.py @@ -1,5 +1,6 @@ from django.contrib import admin from django.contrib.admin.options import forms +from import_export.admin import ExportActionMixin, ImportExportModelAdmin from meshapi.admin.inlines import InstallInline from meshapi.models import Member @@ -18,7 +19,7 @@ class Meta: @admin.register(Member) -class MemberAdmin(admin.ModelAdmin): +class MemberAdmin(ImportExportModelAdmin, ExportActionMixin): form = MemberAdminForm search_fields = [ # Search by name diff --git a/src/meshapi/admin/node.py b/src/meshapi/admin/node.py index d1c3138c7..6451f1658 100644 --- a/src/meshapi/admin/node.py +++ b/src/meshapi/admin/node.py @@ -1,5 +1,7 @@ from django.contrib import admin from django.contrib.admin.options import forms +from import_export import resources +from import_export.admin import ExportActionMixin, ImportExportModelAdmin from meshapi.admin.inlines import ( BuildingMembershipInline, @@ -17,6 +19,17 @@ admin.site.index_title = "Welcome to MeshDB Admin Portal" +class NodeImportExportResource(resources.ModelResource): + def before_import(self, dataset, **kwargs): + if "network_number" not in dataset.headers: + dataset.headers.append("network_number") + super().before_import(dataset, **kwargs) + + class Meta: + model = Node + import_id_fields = ("network_number",) + + class NodeAdminForm(forms.ModelForm): class Meta: model = Node @@ -24,8 +37,9 @@ class Meta: @admin.register(Node) -class NodeAdmin(admin.ModelAdmin): +class NodeAdmin(ImportExportModelAdmin, ExportActionMixin): form = NodeAdminForm + resource_classes = [NodeImportExportResource] search_fields = [ "network_number__iexact", "name__icontains", diff --git a/src/meshapi/admin/sector.py b/src/meshapi/admin/sector.py index 0c925f004..9c74adb92 100644 --- a/src/meshapi/admin/sector.py +++ b/src/meshapi/admin/sector.py @@ -1,5 +1,6 @@ from django.contrib import admin from django.contrib.admin.options import forms +from import_export.admin import ExportActionMixin, ImportExportModelAdmin from meshapi.admin.admin import device_fieldsets from meshapi.admin.inlines import DeviceLinkInline @@ -13,7 +14,7 @@ class Meta: @admin.register(Sector) -class SectorAdmin(admin.ModelAdmin): +class SectorAdmin(ImportExportModelAdmin, ExportActionMixin): form = SectorAdminForm search_fields = ["name__icontains", "model__icontains", "ssid__icontains", "notes__icontains"] list_display = [ diff --git a/src/meshdb/settings.py b/src/meshdb/settings.py index ab4039ffc..8585c7595 100644 --- a/src/meshdb/settings.py +++ b/src/meshdb/settings.py @@ -94,6 +94,7 @@ "django_filters", "django_jsonform", "dbbackup", + "import_export", ] MIDDLEWARE = [ @@ -299,3 +300,6 @@ "docExpansion": "none", }, } + +IMPORT_EXPORT_IMPORT_PERMISSION_CODE = "add" +IMPORT_EXPORT_EXPORT_PERMISSION_CODE = "view"