96 lines
4.2 KiB
Python
96 lines
4.2 KiB
Python
from django.forms import TypedMultipleChoiceField
|
|
from django.db.models.query import QuerySet
|
|
from django.http import HttpRequest
|
|
from django.contrib import admin, messages
|
|
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
|
|
|
|
from ..actions.assign_profile import assign_profile
|
|
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)
|
|
|
|
# Form class to assing aircrafts to instructors
|
|
class AssignAircraftForm(AdminActionForm):
|
|
aircrafts = TypedMultipleChoiceField(choices=AircraftTypes)
|
|
|
|
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:
|
|
return SafeText(obj.default_password())
|
|
|
|
@admin.display(description="Username")
|
|
def username(self, obj: Instructor) -> SafeText:
|
|
return SafeText(obj.default_username())
|
|
|
|
@admin.display(description="Assigned Profiles")
|
|
def assigned_profiles(self, obj: Instructor) -> SafeText:
|
|
if not obj.aircrafts:
|
|
return SafeText("")
|
|
return SafeText("/".join(mix.mtype for mix in obj.missions.distinct("mtype").order_by("mtype").all()))
|
|
|
|
@admin.display(description="Assigned Aircrafts")
|
|
def assigned_aircrafts(self, obj: Instructor) -> SafeText:
|
|
if not obj.aircrafts:
|
|
return SafeText("")
|
|
return SafeText("/".join(ac.type for ac in obj.aircrafts.distinct("type").order_by("type").all()))
|
|
|
|
@action_with_form(AssignAircraftForm, description="Assign Aircraft Type")
|
|
def assign_aircraft(self, request: HttpRequest, queryset: QuerySet[Instructor], data: Dict[str, List[AircraftTypes]]):
|
|
i: int
|
|
ac_types: List[str]
|
|
i, ac_types = assign_aircraft(queryset=queryset, data=data)
|
|
messages.success(request, f"{i} Instructors updated to {ac_types}")
|
|
|
|
@action_with_form(AssignMissionForm, description="Assign Mission Type")
|
|
def assign_profile(self, request: HttpRequest, queryset: QuerySet[Instructor], data: Dict[str, List[MissionTypes]]):
|
|
i: int
|
|
mix_types: List[str]
|
|
i, mix_types = assign_profile(queryset=queryset, data=data)
|
|
messages.success(request, f"{i} Instructors updated to {mix_types}")
|