From 7a392df8ad7d1ba274762d4b198f6c3634145ae2 Mon Sep 17 00:00:00 2001 From: Emanuele Date: Fri, 28 Nov 2025 11:04:12 +0100 Subject: [PATCH] Added assigned aircrafts to mission profiles --- cntmanage/flightslot/admins/mission_adm.py | 51 +++++++++++++++---- .../0023_missionprofile_aircrafts.py | 18 +++++++ cntmanage/flightslot/models/missions.py | 5 ++ 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 cntmanage/flightslot/migrations/0023_missionprofile_aircrafts.py diff --git a/cntmanage/flightslot/admins/mission_adm.py b/cntmanage/flightslot/admins/mission_adm.py index b44f95f..c1fdd06 100644 --- a/cntmanage/flightslot/admins/mission_adm.py +++ b/cntmanage/flightslot/admins/mission_adm.py @@ -1,17 +1,21 @@ -from django.contrib import admin +from django.forms import ModelChoiceField, TypedMultipleChoiceField, ModelMultipleChoiceField +from django.contrib import admin, messages +from django.http import HttpRequest +from django.db.models.query import QuerySet, Q from django.utils.safestring import SafeText -from typing import Any +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.aircrafts import Aircraft from ..models.missions import MissionProfile -from django_admin_action_forms import AdminActionFormsMixin - from datetime import timedelta +from typing import Any, Dict # Resource Class for Student data import class MissionProfileResource(ModelResource): @@ -31,9 +35,38 @@ class MissionProfileResource(ModelResource): model = MissionProfile skip_unchanged = True report_skipped = True - fields = ("mtype", "mnum", "duration") - import_id_fields = ("mtype", "mnum") + fields = ("mtype", "mnum", "duration",) + import_id_fields = ("mtype", "mnum",) -class MissionProfileAdmin(AdminActionFormsMixin, ImportMixin, admin.ModelAdmin): - list_display = ("mtype", "mnum", "notes") - list_filter = ("mtype",) +# Form class to assing aircrafts to students +class ChangeAircraftForm(AdminActionForm): + aircrafts = ModelMultipleChoiceField(queryset=Aircraft.objects.distinct('type').all()) + +class MissionProfileAdmin(ImportMixin, AdminActionFormsMixin, admin.ModelAdmin): + list_display = ("mtype", "mnum", "assigned_aircrafts", "duration", "notes", ) + list_filter = ("mtype", ) + actions = ("assign_aircraft", ) + tmp_storage_class = CacheStorage + skip_admin_log = True + + @action_with_form(ChangeAircraftForm, description="Assign Aircraft") + def assign_aircraft(self, request: HttpRequest, queryset: QuerySet[MissionProfile], data: Dict[str, QuerySet[Aircraft]]): + ac_types = [t.type for t in data["aircrafts"]] + ac_query: Q = Q() # Build an or query to select all aircrafts of the specified types + for a in ac_types: + ac_query |= Q(type=a) + aircrafts: QuerySet[Aircraft] = Aircraft.objects.filter(ac_query).all() # Execute query + i: int = 0 + for mix in queryset: + mix.aircrafts.clear() + for ac in aircrafts: + mix.aircrafts.add(ac) + mix.save() + i += 1 + messages.success(request, f"{i} Students updated to {ac_types}") + + @admin.display(description="Assigned Aircrafts") + def assigned_aircrafts(self, obj: MissionProfile) -> SafeText: + if not obj.aircrafts: + return SafeText("") + return SafeText("/".join(ac.markings for ac in obj.aircrafts.all())) \ No newline at end of file diff --git a/cntmanage/flightslot/migrations/0023_missionprofile_aircrafts.py b/cntmanage/flightslot/migrations/0023_missionprofile_aircrafts.py new file mode 100644 index 0000000..32d0789 --- /dev/null +++ b/cntmanage/flightslot/migrations/0023_missionprofile_aircrafts.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.8 on 2025-11-28 09:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('flightslot', '0022_aircraft_alter_course_color_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='missionprofile', + name='aircrafts', + field=models.ManyToManyField(to='flightslot.aircraft'), + ), + ] diff --git a/cntmanage/flightslot/models/missions.py b/cntmanage/flightslot/models/missions.py index 2be822d..235eea0 100644 --- a/cntmanage/flightslot/models/missions.py +++ b/cntmanage/flightslot/models/missions.py @@ -3,6 +3,7 @@ from django.db import models from datetime import timedelta from ..models.weekpref import WeekPreference +from ..models.aircrafts import Aircraft class MissionType(models.TextChoices): OTHER = "OTHER", _("OTHER") @@ -37,6 +38,10 @@ class MissionProfile(models.Model): default=timedelta(hours=1) ) + aircrafts = models.ManyToManyField( + Aircraft + ) + notes = models.TextField( max_length=140, null=True,