airplane-class #2
@@ -1,11 +1,13 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
|
||||||
|
from .models.aircrafts import Aircraft
|
||||||
from .models.courses import Course
|
from .models.courses import Course
|
||||||
from .models.students import Student
|
from .models.students import Student
|
||||||
from .models.missions import MissionProfile
|
from .models.missions import MissionProfile
|
||||||
from .models.weekpref import WeekPreference
|
from .models.weekpref import WeekPreference
|
||||||
|
|
||||||
|
from .admins.aircraft_adm import AircraftAdmin
|
||||||
from .admins.course_adm import CourseAdmin
|
from .admins.course_adm import CourseAdmin
|
||||||
from .admins.student_adm import StudentAdmin
|
from .admins.student_adm import StudentAdmin
|
||||||
from .admins.mission_adm import MissionProfileAdmin
|
from .admins.mission_adm import MissionProfileAdmin
|
||||||
@@ -35,6 +37,7 @@ admin.site.site_header = "Flight Scheduler Admin 🛫"
|
|||||||
admin.site.site_title = "Flight Scheduler Admin 🛫"
|
admin.site.site_title = "Flight Scheduler Admin 🛫"
|
||||||
admin.site.index_title = "Welcome to CantorAir Flight Scheduler Administrator Portal"
|
admin.site.index_title = "Welcome to CantorAir Flight Scheduler Administrator Portal"
|
||||||
|
|
||||||
|
admin.site.register(Aircraft, AircraftAdmin)
|
||||||
admin.site.register(Course, CourseAdmin)
|
admin.site.register(Course, CourseAdmin)
|
||||||
admin.site.register(MissionProfile, MissionProfileAdmin)
|
admin.site.register(MissionProfile, MissionProfileAdmin)
|
||||||
admin.site.register(Student, StudentAdmin)
|
admin.site.register(Student, StudentAdmin)
|
||||||
|
|||||||
17
cntmanage/flightslot/admins/aircraft_adm.py
Normal file
17
cntmanage/flightslot/admins/aircraft_adm.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
from django.db.models.query import QuerySet
|
||||||
|
from django.http import HttpRequest
|
||||||
|
|
||||||
|
from ..models.aircrafts import Aircraft
|
||||||
|
|
||||||
|
class AircraftAdmin(admin.ModelAdmin):
|
||||||
|
model = Aircraft
|
||||||
|
list_display = ("type", "markings", "avail_hours", "complex", )
|
||||||
|
list_filter = ("type", )
|
||||||
|
actions = ("reset_maint")
|
||||||
|
|
||||||
|
def get_queryset(self, request: HttpRequest) -> QuerySet[Aircraft]:
|
||||||
|
qs: QuerySet[Aircraft] = super().get_queryset(request)
|
||||||
|
qs.order_by("type", "markings")
|
||||||
|
return qs
|
||||||
|
|
||||||
@@ -73,15 +73,15 @@ class HourBuildingInLine(nested_admin.NestedTabularInline):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# If user is a student deny edit permission for week past the current one
|
# If user is a student deny edit permission for week past the current one
|
||||||
def has_change_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
def has_change_permission(self, request: HttpRequest, obj: WeekPreference | None = None) -> bool:
|
||||||
if hasattr(request.user, 'student') and obj:
|
if hasattr(request.user, 'student') and obj:
|
||||||
current_week: int = date.today().isocalendar().week
|
current_week: int = date.today().isocalendar().week
|
||||||
if current_week > obj.week:
|
if current_week > obj.week:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def has_delete_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
def has_delete_permission(self, request: HttpRequest, obj: WeekPreference | None = None) -> bool:
|
||||||
return self.has_change_permission(request=request, obj=obj)
|
return self.has_change_permission(request=request, obj=obj)
|
||||||
|
|
||||||
def has_add_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
def has_add_permission(self, request: HttpRequest, obj: WeekPreference | None = None) -> bool:
|
||||||
return self.has_change_permission(request=request, obj=obj)
|
return self.has_change_permission(request=request, obj=obj)
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ class MissionProfileResource(ModelResource):
|
|||||||
duration = fields.Field(attribute="duration", column_name="duration")
|
duration = fields.Field(attribute="duration", column_name="duration")
|
||||||
|
|
||||||
# Cleanup fields before entering
|
# Cleanup fields before entering
|
||||||
def before_import_row(self, row: dict[str, str | Any], **kwargs) -> None:
|
def before_import_row(self, row: dict[str, str | Any], **kwargs):
|
||||||
row["mtype"] = SafeText(row["mtype"].upper().strip())
|
row["mtype"] = SafeText(row["mtype"].upper().strip())
|
||||||
row["mnum"] = SafeText(row["mnum"].upper().strip())
|
row["mnum"] = SafeText(row["mnum"].upper().strip())
|
||||||
h, m, _ = row["duration"].split(":")
|
h, m, _ = row["duration"].split(":")
|
||||||
row["duration"] = timedelta(hours=float(h), minutes=float(m))
|
row["duration"] = timedelta(hours=float(h), minutes=float(m))
|
||||||
return super().before_import_row(row, **kwargs)
|
super().before_import_row(row, **kwargs)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = MissionProfile
|
model = MissionProfile
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from django import forms
|
from django.forms import ModelChoiceField, TypedMultipleChoiceField, ModelMultipleChoiceField
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet, Q
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.contrib import admin, messages
|
from django.contrib import admin, messages
|
||||||
from django.utils.safestring import SafeText
|
from django.utils.safestring import SafeText
|
||||||
@@ -12,16 +12,17 @@ from import_export.forms import ConfirmImportForm, ImportForm
|
|||||||
|
|
||||||
from django_admin_action_forms import AdminActionFormsMixin, AdminActionForm, action_with_form
|
from django_admin_action_forms import AdminActionFormsMixin, AdminActionForm, action_with_form
|
||||||
|
|
||||||
from typing import Any, Dict
|
from ..models.aircrafts import Aircraft, AircraftTypes
|
||||||
|
|
||||||
from ..models.courses import Course
|
from ..models.courses import Course
|
||||||
from ..models.students import Student
|
from ..models.students import Student
|
||||||
|
|
||||||
from ..custom.colortag import course_color
|
from ..custom.colortag import course_color
|
||||||
|
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
# Custom import form to select a course for student input
|
# Custom import form to select a course for student input
|
||||||
class StudentCustomConfirmImportForm(ConfirmImportForm):
|
class StudentCustomConfirmImportForm(ConfirmImportForm):
|
||||||
course = forms.ModelChoiceField(
|
course = ModelChoiceField(
|
||||||
queryset=Course.objects.all(),
|
queryset=Course.objects.all(),
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
@@ -55,13 +56,18 @@ class StudentResource(ModelResource):
|
|||||||
|
|
||||||
# Form Class for Student course change
|
# Form Class for Student course change
|
||||||
class ChangeCourseForm(AdminActionForm):
|
class ChangeCourseForm(AdminActionForm):
|
||||||
course = forms.ModelChoiceField(queryset=Course.objects.all())
|
course = TypedMultipleChoiceField(choices=AircraftTypes)
|
||||||
|
|
||||||
|
# Form class to assing aircrafts to students
|
||||||
|
class ChangeAircraftForm(AdminActionForm):
|
||||||
|
aircrafts = ModelMultipleChoiceField(queryset=Aircraft.objects.distinct('type').all())
|
||||||
|
|
||||||
class StudentAdmin(ImportMixin, AdminActionFormsMixin, admin.ModelAdmin):
|
class StudentAdmin(ImportMixin, AdminActionFormsMixin, admin.ModelAdmin):
|
||||||
|
model = Student
|
||||||
list_display = ("surname", "name", "course", "course_color", "email", "phone", "username", "password", "active", )
|
list_display = ("surname", "name", "course", "course_color", "email", "phone", "username", "password", "active", )
|
||||||
list_filter = ("course", "active", )
|
list_filter = ("course", "active", )
|
||||||
search_fields = ("surname", "name", "phone", "email", )
|
search_fields = ("surname", "name", "phone", "email", )
|
||||||
actions = ("change_course", "disable_students",)
|
actions = ("change_course", "disable_students", "change_aircraft", )
|
||||||
resource_classes = [StudentResource]
|
resource_classes = [StudentResource]
|
||||||
confirm_form_class = StudentCustomConfirmImportForm
|
confirm_form_class = StudentCustomConfirmImportForm
|
||||||
tmp_storage_class = CacheStorage
|
tmp_storage_class = CacheStorage
|
||||||
@@ -89,7 +95,6 @@ class StudentAdmin(ImportMixin, AdminActionFormsMixin, admin.ModelAdmin):
|
|||||||
q.user.save()
|
q.user.save()
|
||||||
count: int = queryset.update(active = False)
|
count: int = queryset.update(active = False)
|
||||||
messages.success(request, f"{count} students deactivated")
|
messages.success(request, f"{count} students deactivated")
|
||||||
pass
|
|
||||||
|
|
||||||
@action_with_form(ChangeCourseForm, description="Change Student Course")
|
@action_with_form(ChangeCourseForm, description="Change Student Course")
|
||||||
def change_course(self, request: HttpRequest, queryset: QuerySet[Student], data):
|
def change_course(self, request: HttpRequest, queryset: QuerySet[Student], data):
|
||||||
@@ -97,16 +102,32 @@ class StudentAdmin(ImportMixin, AdminActionFormsMixin, admin.ModelAdmin):
|
|||||||
count: int = queryset.update(course=course)
|
count: int = queryset.update(course=course)
|
||||||
messages.success(request, f"{count} students updated to {course}")
|
messages.success(request, f"{count} students updated to {course}")
|
||||||
|
|
||||||
|
@action_with_form(ChangeAircraftForm, description="Assign Aircraft")
|
||||||
|
def change_aircraft(self, request: HttpRequest, queryset: QuerySet[Student], 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 student in queryset:
|
||||||
|
student.aircrafts.clear()
|
||||||
|
for ac in aircrafts:
|
||||||
|
student.aircrafts.add(ac)
|
||||||
|
student.save()
|
||||||
|
i += 1
|
||||||
|
messages.success(request, f"{i} Students updated to {ac_types}")
|
||||||
|
|
||||||
# Return the initial form for import confirmations, request course to user
|
# Return the initial form for import confirmations, request course to user
|
||||||
def get_confirm_form_initial(self, request: HttpRequest, import_form):
|
def get_confirm_form_initial(self, request: HttpRequest, import_form) -> Dict[str, Any]:
|
||||||
initial = super().get_confirm_form_initial(request, import_form)
|
initial: Dict[str, Any] = super().get_confirm_form_initial(request, import_form)
|
||||||
if import_form and hasattr(import_form.cleaned_data, "course"):
|
if import_form and hasattr(import_form.cleaned_data, "course"):
|
||||||
course: Course = import_form.cleaned_data["course"]
|
course: Course = import_form.cleaned_data["course"]
|
||||||
initial["course"] = course.id
|
initial["course"] = course.id
|
||||||
return initial
|
return initial
|
||||||
|
|
||||||
# Add course to import form kwargs to be used by resource to associate course with all imported students
|
# Add course to import form kwargs to be used by resource to associate course with all imported students
|
||||||
def get_import_data_kwargs(self, request: HttpRequest, *args, **kwargs):
|
def get_import_data_kwargs(self, request: HttpRequest, *args, **kwargs) -> Dict[str, Any]:
|
||||||
form: ImportForm | None = kwargs.get("form", None)
|
form: ImportForm | None = kwargs.get("form", None)
|
||||||
if form and hasattr(form, "cleaned_data"):
|
if form and hasattr(form, "cleaned_data"):
|
||||||
kwargs["course"] = form.cleaned_data.get("course", None)
|
kwargs["course"] = form.cleaned_data.get("course", None)
|
||||||
|
|||||||
@@ -26,15 +26,15 @@ class TrainingInLIne(nested_admin.NestedTabularInline):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# If user is a student deny edit permission for week past the current one
|
# If user is a student deny edit permission for week past the current one
|
||||||
def has_change_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
def has_change_permission(self, request: HttpRequest, obj: WeekPreference | None = None) -> bool:
|
||||||
if hasattr(request.user, 'student') and obj:
|
if hasattr(request.user, 'student') and obj:
|
||||||
current_week: int = date.today().isocalendar().week
|
current_week: int = date.today().isocalendar().week
|
||||||
if current_week > obj.week:
|
if current_week > obj.week:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def has_delete_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
def has_delete_permission(self, request: HttpRequest, obj: WeekPreference | None = None) -> bool:
|
||||||
return self.has_change_permission(request=request, obj=obj)
|
return self.has_change_permission(request=request, obj=obj)
|
||||||
|
|
||||||
def has_add_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
def has_add_permission(self, request: HttpRequest, obj: WeekPreference | None = None) -> bool:
|
||||||
return self.has_change_permission(request=request, obj=obj)
|
return self.has_change_permission(request=request, obj=obj)
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import nested_admin
|
import nested_admin
|
||||||
|
|
||||||
from django import forms
|
from django.forms import Form
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
from django.contrib.auth.models import User
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.contrib import admin, messages
|
from django.contrib import admin, messages
|
||||||
from django.utils.translation import ngettext
|
from django.utils.translation import ngettext
|
||||||
@@ -17,6 +18,7 @@ from ..custom.colortag import course_color
|
|||||||
from ..actions.exportweek import export_selected
|
from ..actions.exportweek import export_selected
|
||||||
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
from typing import Dict, List, Any
|
||||||
|
|
||||||
class WeekPreferenceAdmin(nested_admin.NestedPolymorphicModelAdmin):
|
class WeekPreferenceAdmin(nested_admin.NestedPolymorphicModelAdmin):
|
||||||
inlines = (TrainingInLIne, HourBuildingInLine, )
|
inlines = (TrainingInLIne, HourBuildingInLine, )
|
||||||
@@ -45,83 +47,75 @@ class WeekPreferenceAdmin(nested_admin.NestedPolymorphicModelAdmin):
|
|||||||
return course_color(obj.student.course.color)
|
return course_color(obj.student.course.color)
|
||||||
|
|
||||||
# If a user is registered as student hide filters
|
# If a user is registered as student hide filters
|
||||||
def get_list_filter(self, request):
|
def get_list_filter(self, request: HttpRequest) -> List[str]:
|
||||||
list_filter = super().get_list_filter(request)
|
list_filter = super().get_list_filter(request)
|
||||||
if hasattr(request.user, 'student'):
|
if hasattr(request.user, "student"):
|
||||||
return []
|
return []
|
||||||
return list_filter
|
return list_filter
|
||||||
|
|
||||||
# If a user is registered as student do not show actions
|
# If a user is registered as student do not show actions
|
||||||
def get_actions(self, request):
|
def get_actions(self, request: HttpRequest) -> Dict[str, Any]:
|
||||||
actions = super().get_actions(request)
|
actions = super().get_actions(request)
|
||||||
if hasattr(request.user, 'student'):
|
if hasattr(request.user, "student"):
|
||||||
return []
|
return {}
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
# If a user is registered as student show only their preferences
|
# If a user is registered as student show only their preferences
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request: HttpRequest) -> QuerySet[WeekPreference]:
|
||||||
qs = super().get_queryset(request)
|
qs = super().get_queryset(request)
|
||||||
if hasattr(request.user, 'student'):
|
if hasattr(request.user, "student"):
|
||||||
return qs.filter(student=request.user.student)
|
return qs.filter(student=request.user.student)
|
||||||
# If admin show everything
|
# If admin show everything
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def get_form(self, request, obj=None, **kwargs):
|
def get_form(self, request: HttpRequest, obj: WeekPreference | None = None, **kwargs: Dict[str, Any]) -> Form:
|
||||||
form: forms.Form = super().get_form(request, obj, **kwargs)
|
form: Form = super().get_form(request, obj, **kwargs)
|
||||||
current_week = date.today().isocalendar().week
|
current_week = date.today().isocalendar().week
|
||||||
|
|
||||||
# If form contains the week field
|
# If form contains the week field
|
||||||
if 'week' in form.base_fields:
|
if "week" in form.base_fields:
|
||||||
# Set default value as current week
|
# Set default value as current week
|
||||||
form.base_fields['week'].initial = current_week
|
form.base_fields["week"].initial = current_week
|
||||||
|
|
||||||
# If student is current user making request
|
# If student is current user making request
|
||||||
if hasattr(request.user, 'student'):
|
if hasattr(request.user, "student"):
|
||||||
student = request.user.student
|
student = request.user.student
|
||||||
if 'student' in form.base_fields:
|
if "student" in form.base_fields:
|
||||||
form.base_fields['student'].initial = student
|
form.base_fields["student"].initial = student
|
||||||
form.base_fields['student'].disabled = True
|
form.base_fields["student"].disabled = True
|
||||||
form.base_fields['week'].disabled = True # student cannot change week
|
form.base_fields["week"].disabled = True # student cannot change week
|
||||||
return form
|
return form
|
||||||
|
|
||||||
# If user is a student deny edit permission for week past the current one
|
# If user is a student deny edit permission for week past the current one
|
||||||
def has_change_permission(self, request, obj: WeekPreference | None = None):
|
def has_change_permission(self, request: HttpRequest, obj: WeekPreference | None = None) -> bool:
|
||||||
if hasattr(request.user, 'student') and obj:
|
if hasattr(request.user, "student") and obj:
|
||||||
current_week = date.today().isocalendar().week
|
current_week = date.today().isocalendar().week
|
||||||
if current_week > obj.week:
|
if current_week > obj.week:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# If user is a student deny edit permission for week past the current one
|
# If user is a student deny edit permission for week past the current one
|
||||||
def has_add_permission(self, request, obj: WeekPreference | None = None):
|
def has_add_permission(self, request: HttpRequest, obj: WeekPreference | None = None) -> bool:
|
||||||
if hasattr(request.user, 'student') and obj:
|
return self.has_change_permission(request, obj)
|
||||||
current_week = date.today().isocalendar().week
|
|
||||||
if current_week > obj.week:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
# If user is a student deny edit permission for week past the current one
|
# If user is a student deny edit permission for week past the current one
|
||||||
def has_delete_permission(self, request, obj: WeekPreference | None = None):
|
def has_delete_permission(self, request: HttpRequest, obj: WeekPreference | None = None)-> bool:
|
||||||
if hasattr(request.user, 'student') and obj:
|
return self.has_change_permission(request, obj)
|
||||||
current_week = date.today().isocalendar().week
|
|
||||||
if current_week > obj.week:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def changeform_view(self, request: HttpRequest, object_id: int | None = None, form_url: str = '', extra_context=None):
|
def changeform_view(self, request: HttpRequest, object_id: int | None = None, form_url: str = "", extra_context=None):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
if hasattr(request.user, 'student') and object_id:
|
if hasattr(request.user, "student") and object_id:
|
||||||
current_week = date.today().isocalendar().week
|
current_week = date.today().isocalendar().week
|
||||||
weekpref = WeekPreference.objects.get(id=object_id)
|
weekpref = WeekPreference.objects.get(id=object_id)
|
||||||
if current_week > weekpref.week:
|
if current_week > weekpref.week:
|
||||||
extra_context['show_save'] = False
|
extra_context["show_save"] = False
|
||||||
extra_context['show_save_and_continue'] = False
|
extra_context["show_save_and_continue"] = False
|
||||||
extra_context['show_save_and_add_another'] = False
|
extra_context["show_save_and_add_another"] = False
|
||||||
extra_context['show_delete'] = False
|
extra_context["show_delete"] = False
|
||||||
return super().changeform_view(request, object_id, form_url, extra_context)
|
return super().changeform_view(request, object_id, form_url, extra_context)
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request: HttpRequest, obj, form: Form, change: bool):
|
||||||
# Imposta automaticamente lo studente se non è già valorizzato
|
# Imposta automaticamente lo studente se non è già valorizzato
|
||||||
if hasattr(request.user, 'student') and not obj.student_id:
|
if hasattr(request.user, "student") and not obj.student_id:
|
||||||
obj.student = request.user.student
|
obj.student = request.user.student
|
||||||
super().save_model(request, obj, form, change)
|
super().save_model(request, obj, form, change)
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# Generated by Django 5.2.8 on 2025-11-27 13:34
|
||||||
|
|
||||||
|
import colorfield.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('flightslot', '0021_alter_hourbuildinglegstop_refuel'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Aircraft',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('type', models.CharField(choices=[('C152', 'Cessna 152'), ('P208', 'Tecnam P2008'), ('PA28', 'Piper PA28R'), ('PA34', 'Piper PA34'), ('C182', 'Cessna 182Q'), ('TWEN', 'Tecnam P2010'), ('FSTD', 'Alsim ALX40')], max_length=4)),
|
||||||
|
('markings', models.CharField(max_length=6)),
|
||||||
|
('complex', models.BooleanField(default=False)),
|
||||||
|
('avail_hours', models.DurationField(null=True, verbose_name='Time until maintenance')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='course',
|
||||||
|
name='color',
|
||||||
|
field=colorfield.fields.ColorField(default='#FFFFFF', image_field=None, max_length=25, samples=[('#bfbfbf', 'GREY'), ('#ff0000', 'RED'), ('#ffc000', 'ORANGE'), ('#ffff00', 'YELLOW'), ('#92d050', 'GREEN'), ('#00b0f0', 'CYAN'), ('#b1a0c7', 'MAGENTA'), ('#fabcfb', 'PINK'), ('#f27ae4', 'VIOLET')], verbose_name='Binder Color'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hourbuilding',
|
||||||
|
name='aircraft',
|
||||||
|
field=models.CharField(choices=[('C152', 'Cessna 152'), ('P208', 'Tecnam P2008'), ('PA28', 'Piper PA28R'), ('PA34', 'Piper PA34'), ('C182', 'Cessna 182Q'), ('TWEN', 'Tecnam P2010'), ('FSTD', 'Alsim ALX40')]),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='student',
|
||||||
|
name='aircrafts',
|
||||||
|
field=models.ManyToManyField(to='flightslot.aircraft'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -5,5 +5,45 @@ class AircraftTypes(models.TextChoices):
|
|||||||
C152 = "C152", _("Cessna 152")
|
C152 = "C152", _("Cessna 152")
|
||||||
P208 = "P208", _("Tecnam P2008")
|
P208 = "P208", _("Tecnam P2008")
|
||||||
PA28 = "PA28", _("Piper PA28R")
|
PA28 = "PA28", _("Piper PA28R")
|
||||||
|
PA34 = "PA34", _("Piper PA34")
|
||||||
C182 = "C182", _("Cessna 182Q")
|
C182 = "C182", _("Cessna 182Q")
|
||||||
P210 = "TWEN", _("Tecnam P2010")
|
P210 = "TWEN", _("Tecnam P2010")
|
||||||
|
ALX40 = "FSTD", _("Alsim ALX40")
|
||||||
|
|
||||||
|
class Aircraft(models.Model):
|
||||||
|
id = models.AutoField(
|
||||||
|
primary_key=True
|
||||||
|
)
|
||||||
|
|
||||||
|
type = models.CharField(
|
||||||
|
null=False,
|
||||||
|
blank=False,
|
||||||
|
max_length=4, # ICAO naming of aircraft,
|
||||||
|
choices=AircraftTypes
|
||||||
|
)
|
||||||
|
|
||||||
|
markings = models.CharField(
|
||||||
|
null=False,
|
||||||
|
blank=False,
|
||||||
|
max_length=6
|
||||||
|
)
|
||||||
|
|
||||||
|
complex = models.BooleanField(
|
||||||
|
null=False,
|
||||||
|
default=False
|
||||||
|
)
|
||||||
|
|
||||||
|
avail_hours = models.DurationField(
|
||||||
|
null=True,
|
||||||
|
verbose_name=_("Time until maintenance")
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return f"{self.type} ({self.markings})"
|
||||||
|
|
||||||
|
# Insert dash between first and rest, I-OASM
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
self.markings = self.markings.upper()
|
||||||
|
if not "-" in self.markings:
|
||||||
|
self.markings = self.markings[0] + "-" + self.markings[1:]
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|||||||
@@ -10,14 +10,18 @@ class CourseTypes(models.TextChoices):
|
|||||||
DISTANCE = "DL", _("DISTANCE")
|
DISTANCE = "DL", _("DISTANCE")
|
||||||
OTHER = "OTHER",_("OTHER")
|
OTHER = "OTHER",_("OTHER")
|
||||||
|
|
||||||
|
|
||||||
class Course(models.Model):
|
class Course(models.Model):
|
||||||
# Add colors according to table from Alessia
|
# Add colors according to table from Alessia
|
||||||
COLOR_PALETTE = [
|
COLOR_PALETTE = [
|
||||||
("#ffffff","WHITE"),
|
("#bfbfbf","GREY"),
|
||||||
("#ff0000", "RED"),
|
("#ff0000", "RED"),
|
||||||
("#00ff00", "GREEN"),
|
("#ffc000", "ORANGE"),
|
||||||
("#0000ff", "BLUE")
|
("#ffff00", "YELLOW"),
|
||||||
|
("#92d050", "GREEN"),
|
||||||
|
("#00b0f0", "CYAN"),
|
||||||
|
("#b1a0c7", "MAGENTA"),
|
||||||
|
("#fabcfb", "PINK"),
|
||||||
|
("#f27ae4", "VIOLET"),
|
||||||
]
|
]
|
||||||
|
|
||||||
id = models.AutoField(
|
id = models.AutoField(
|
||||||
@@ -43,8 +47,8 @@ class Course(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
color = ColorField (
|
color = ColorField (
|
||||||
samples=COLOR_PALETTE,
|
verbose_name=_("Binder Color"),
|
||||||
verbose_name=_("Binder Color")
|
samples=COLOR_PALETTE
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from django.db import models
|
|||||||
from django.contrib.auth.models import User, Group
|
from django.contrib.auth.models import User, Group
|
||||||
|
|
||||||
from ..models.courses import Course
|
from ..models.courses import Course
|
||||||
|
from ..models.aircrafts import Aircraft
|
||||||
|
|
||||||
class Student(models.Model):
|
class Student(models.Model):
|
||||||
id = models.AutoField(
|
id = models.AutoField(
|
||||||
@@ -46,6 +47,10 @@ class Student(models.Model):
|
|||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
aircrafts = models.ManyToManyField(
|
||||||
|
Aircraft
|
||||||
|
)
|
||||||
|
|
||||||
def default_password(self) -> str: # Maximum 4 digits for passowrd
|
def default_password(self) -> str: # Maximum 4 digits for passowrd
|
||||||
return f"{self.name.lower()[0]}{self.surname.lower()}{self.id % 10000}"
|
return f"{self.name.lower()[0]}{self.surname.lower()}{self.id % 10000}"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user