From 4b5319f557e6f5d663a97b71367045bbbc460b33 Mon Sep 17 00:00:00 2001 From: Emanuele Date: Tue, 2 Dec 2025 12:21:11 +0100 Subject: [PATCH] Instructor import --- cntmanage/flightslot/admin.py | 3 +- .../flightslot/admins/instructor_admin.py | 32 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/cntmanage/flightslot/admin.py b/cntmanage/flightslot/admin.py index f6dd88b..6987d40 100644 --- a/cntmanage/flightslot/admin.py +++ b/cntmanage/flightslot/admin.py @@ -60,7 +60,8 @@ class FlightSlotStaffSite(AdminSite): # Register only user visible models flightslot_staff = FlightSlotUserSite(name="staff_site") flightslot_staff.register(Availability, AvailabilityAdmin) - +flightslot_staff.register(MissionProfile, MissionProfileAdmin) +flightslot_staff.register(Instructor, InstructorAdmin) # Get version for debug purposes ver: str = environ.get("VERSION", "dev") diff --git a/cntmanage/flightslot/admins/instructor_admin.py b/cntmanage/flightslot/admins/instructor_admin.py index 154dabf..a3d5c64 100644 --- a/cntmanage/flightslot/admins/instructor_admin.py +++ b/cntmanage/flightslot/admins/instructor_admin.py @@ -6,6 +6,11 @@ from django.utils.safestring import SafeText from django_admin_action_forms import AdminActionFormsMixin, AdminActionForm, action_with_form +from import_export import fields +from import_export.admin import ImportMixin +from import_export.tmp_storages import CacheStorage +from import_export.resources import ModelResource + from ..models.instructors import Instructor from ..models.aircrafts import AircraftTypes from ..models.missions import MissionTypes @@ -15,6 +20,28 @@ from ..actions.assign_aircraft import assign_aircraft from typing import Dict, List +# Resource Class for Instructor data import +class InstructorResource(ModelResource): + surname = fields.Field(attribute="surname", column_name="surname") + name = fields.Field(attribute="name", column_name="name") + email = fields.Field(attribute="email", column_name="email") + phone = fields.Field(attribute="phone", column_name="phone") + + # Cleanup fields before entering + def before_import_row(self, row: Dict[str, str], **kwargs) -> None: + row["name"] = SafeText("-".join(c.capitalize() for c in row["name"].split(" ")).strip()) + row["surname"] = SafeText("-".join(c.capitalize() for c in row["surname"].split(" ")).strip()) + row["phone"] = SafeText(row["phone"].replace(" ","")) + row["email"] = SafeText(row["email"].lower().strip()) + return super().before_import_row(row, **kwargs) + + class Meta: + model = Instructor + skip_unchanged = True + report_skipped = True + fields = ("surname", "name", "email", "phone", ) + import_id_fields = ("surname", "name", ) + # Form class to assing aircrafts to instructors class AssignMissionForm(AdminActionForm): mission_profiles = TypedMultipleChoiceField(choices=MissionTypes) @@ -23,12 +50,15 @@ class AssignMissionForm(AdminActionForm): class AssignAircraftForm(AdminActionForm): aircrafts = TypedMultipleChoiceField(choices=AircraftTypes) -class InstructorAdmin(AdminActionFormsMixin, admin.ModelAdmin): +class InstructorAdmin(ImportMixin, AdminActionFormsMixin, admin.ModelAdmin): model = Instructor list_display = ("surname", "name", "email", "phone", "assigned_profiles", "assigned_aircrafts", "active", ) search_fields = ("surname", "name", "phone", "email", ) readonly_fields = ("username", "password", ) actions = ("assign_aircraft", "assign_profile", ) + resource_classes = [InstructorResource] + tmp_storage_class = CacheStorage + skip_admin_log = True @admin.display(description="Password") def password(self, obj: Instructor) -> SafeText: