2 Commits

Author SHA1 Message Date
78c2e45ca4 Better inLine version with nested_admin 2024-10-20 11:24:24 +02:00
eb9018928f Nested WeekPreference view in admin with nested_inline 2024-10-20 10:46:19 +02:00
8 changed files with 386 additions and 50 deletions

View File

@@ -1,15 +1,37 @@
from django.contrib import admin
import nested_admin
from .models import *
# Register your models here.
admin.site.register(Student, StudentAdmin)
admin.site.register(MissionProfile)
class HourBuildingLegInline(nested_admin.NestedTabularInline):
model = HourBuildingLeg
extra = 1
fk_name = 'hb'
class PreferenceInLIne(admin.TabularInline):
model = Preference
class HourBuildingInLine(nested_admin.NestedTabularInline):
model = HourBuilding
extra = 1
inlines = [HourBuildingLegInline]
fk_name = 'weekpref'
class TrainingInLIne(nested_admin.NestedTabularInline):
model = Training
extra = 0
fk_name = 'weekpref'
class WeekPreferenceAdmin(admin.ModelAdmin):
inlines = [PreferenceInLIne]
class WeekPreferenceAdmin(nested_admin.NestedModelAdmin):
list_display = ('week', 'student')
list_filter = ['week', 'student']
inlines = [TrainingInLIne, HourBuildingInLine]
class StudentAdmin(admin.ModelAdmin):
list_display = ("name", "surname", "course", "active")
list_filter = ["course", "active"]
class CourseAdmin(admin.ModelAdmin):
list_filter = ["ctype"]
admin.site.register(Course, CourseAdmin)
admin.site.register(MissionProfile)
admin.site.register(Student, StudentAdmin)
admin.site.register(WeekPreference, WeekPreferenceAdmin)

View File

@@ -0,0 +1,65 @@
# Generated by Django 5.1.2 on 2024-10-20 07:57
import django.db.models.deletion
import django.db.models.expressions
import django.db.models.functions.datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('flightslot', '0003_alter_missionprofile_mtype'),
]
operations = [
migrations.RenameModel(
old_name='Preference',
new_name='Training',
),
migrations.AddField(
model_name='missionprofile',
name='notes',
field=models.TextField(max_length=140, null=True),
),
migrations.AlterField(
model_name='missionprofile',
name='duration',
field=models.DurationField(default=1),
),
migrations.AlterField(
model_name='missionprofile',
name='mtype',
field=models.CharField(choices=[('OTHER', 'OTHER'), ('PPL', 'PPL'), ('IR', 'IR'), ('CPL', 'CPL'), ('FI', 'FI'), ('PC', 'PC'), ('CHK', 'CHK_6M')], default='PPL'),
),
migrations.AlterField(
model_name='weekpreference',
name='week',
field=models.PositiveSmallIntegerField(auto_created=True, db_index=True, default=django.db.models.expressions.CombinedExpression(django.db.models.functions.datetime.ExtractWeek(django.db.models.functions.datetime.Now()), '+', models.Value(1))),
),
migrations.CreateModel(
name='HourBuilding',
fields=[
('id', models.BigAutoField(primary_key=True, serialize=False)),
('aircraft', models.CharField(choices=[('C152', 'Cessna 152'), ('P208', 'Tecnam P2008'), ('PA28', 'Piper PA28R'), ('C182', 'Cessna 182Q'), ('P210', 'Tecnam P2010')])),
('monday', models.BooleanField(default=True)),
('tuesday', models.BooleanField(default=True)),
('wednesday', models.BooleanField(default=True)),
('thursday', models.BooleanField(default=True)),
('saturday', models.BooleanField(default=True)),
('sunday', models.BooleanField(default=True)),
('weekpref', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='flightslot.weekpreference')),
],
),
migrations.CreateModel(
name='HourBuildingLeg',
fields=[
('id', models.BigAutoField(primary_key=True, serialize=False)),
('departure', models.CharField(default='LILV', max_length=4)),
('destination', models.CharField(default='LILV', max_length=4)),
('time', models.DurationField(default=1)),
('stop', models.BooleanField(default=False)),
('hb', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='flightslot.hourbuilding')),
],
),
]

View File

@@ -0,0 +1,39 @@
# Generated by Django 5.1.2 on 2024-10-20 08:28
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('flightslot', '0004_rename_preference_training_missionprofile_notes_and_more'),
]
operations = [
migrations.AddField(
model_name='hourbuilding',
name='notes',
field=models.TextField(max_length=140, null=True),
),
migrations.AddField(
model_name='training',
name='notes',
field=models.TextField(max_length=140, null=True),
),
migrations.AlterField(
model_name='hourbuilding',
name='weekpref',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='flightslot.weekpreference'),
),
migrations.AlterField(
model_name='training',
name='mission',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='flightslot.missionprofile'),
),
migrations.AlterField(
model_name='training',
name='weekpref',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='flightslot.weekpreference'),
),
]

View File

@@ -0,0 +1,33 @@
# Generated by Django 5.1.2 on 2024-10-20 09:14
import django.db.models.deletion
import django.db.models.functions.datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('flightslot', '0005_hourbuilding_notes_training_notes_and_more'),
]
operations = [
migrations.CreateModel(
name='Course',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('ctype', models.CharField(choices=[('PPL', 'PPL'), ('ATPL', 'ATPL')])),
('cnumber', models.PositiveSmallIntegerField(default=django.db.models.functions.datetime.ExtractYear(django.db.models.functions.datetime.Now()))),
],
),
migrations.AddField(
model_name='student',
name='active',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='student',
name='course',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='flightslot.course'),
),
]

View File

@@ -1,12 +1,31 @@
from django.db import models
from django.contrib import admin
from django.db.models.functions import Now, ExtractWeek
from django.db.models.functions import Now, ExtractWeek, ExtractYear
from django.utils.translation import gettext_lazy as _
# Create your models here.
class StudentAdmin(admin.ModelAdmin):
list_display = ("name", "surname", "email")
list_filter = []
class CourseTypes(models.TextChoices):
PPL = "PPL", _("PPL")
ATPL = "ATPL", _("ATPL")
class Course(models.Model):
id = models.AutoField(
primary_key=True
)
ctype = models.CharField(
null=False,
choices=CourseTypes
)
cnumber = models.PositiveSmallIntegerField(
null=False,
default=ExtractYear(Now())
)
def __str__(self):
return f"{self.ctype}-{self.cnumber}"
class Student(models.Model):
id = models.AutoField(
@@ -28,44 +47,19 @@ class Student(models.Model):
max_length=32
)
class MissionType(models.TextChoices):
OTHER = "OTHER", _("OTHER")
HB = "HB", _("HB")
PPL = "PPL", _("PPL")
IR = "IR", _("IR")
CPL = "CPL", _("CPL")
FI = "FI", _("FI")
PC = "PC", _("PC")
CHK = "CHK", _("CHK_6M")
class MissionProfile(models.Model):
id = models.AutoField(
primary_key=True
course = models.ForeignKey(
Course,
on_delete=models.DO_NOTHING,
null=True
)
mtype = models.CharField(
active = models.BooleanField(
null=False,
default=MissionType.HB,
choices=MissionType
)
mnum = models.PositiveSmallIntegerField(
null=True,
default=0
)
duration = models.DurationField(
null=False
default=True
)
def __str__(self):
if self.mtype is not MissionType.HB:
return f"{self.mtype}_{self.mnum}"
class MissionProfileAdmin(admin.ModelAdmin):
list_display = ("mtype", "mnum")
return f"{self.surname} {self.name[0]}. - {self.course}"
class WeekPreference(models.Model):
id = models.BigAutoField(
@@ -75,7 +69,8 @@ class WeekPreference(models.Model):
week = models.PositiveSmallIntegerField(
null=False,
db_index=True,
db_default=ExtractWeek(Now()) + 1
default=ExtractWeek(Now()) + 1,
auto_created=True
)
student = models.ForeignKey(
@@ -85,8 +80,59 @@ class WeekPreference(models.Model):
on_delete=models.DO_NOTHING
)
def __str__(self):
return f"{self.week} - {self.student.surname} {self.student.name[0]}."
class Preference(models.Model):
class MissionType(models.TextChoices):
OTHER = "OTHER", _("OTHER")
PPL = "PPL", _("PPL")
IR = "IR", _("IR")
CPL = "CPL", _("CPL")
FI = "FI", _("FI")
PC = "PC", _("PC")
CHK = "CHK", _("CHK_6M")
class MissionProfile(models.Model):
id = models.AutoField(
primary_key=True
)
mtype = models.CharField(
null=False,
default=MissionType.PPL,
choices=MissionType
)
mnum = models.PositiveSmallIntegerField(
null=True,
default=0
)
duration = models.DurationField(
null=False,
default=1
)
notes = models.TextField(
max_length=140,
null=True,
blank=True
)
def __str__(self):
return f"{self.mtype} {self.mnum}"
class MissionProfileAdmin(admin.ModelAdmin):
list_display = ("mtype", "mnum")
class AircraftTypes(models.TextChoices):
C152 = "C152", _("Cessna 152")
P208 = "P208", _("Tecnam P2008")
PA28 = "PA28", _("Piper PA28R")
C182 = "C182", _("Cessna 182Q")
P210 = "P210", _("Tecnam P2010")
class HourBuilding(models.Model):
id = models.BigAutoField(
primary_key=True
)
@@ -94,13 +140,12 @@ class Preference(models.Model):
weekpref = models.ForeignKey(
WeekPreference,
null=False,
on_delete=models.DO_NOTHING
on_delete=models.CASCADE
)
mission = models.ForeignKey(
MissionProfile,
null=True,
on_delete=models.DO_NOTHING
aircraft = models.CharField(
null=False,
choices=AircraftTypes
)
monday = models.BooleanField(
@@ -132,3 +177,104 @@ class Preference(models.Model):
default=True,
null=False
)
notes = models.TextField(
max_length=140,
null=True,
blank=True
)
class HourBuildingLeg(models.Model):
id = models.BigAutoField(
primary_key=True
)
hb = models.ForeignKey(
HourBuilding,
on_delete=models.CASCADE
)
departure = models.CharField(
null=False,
blank=False,
default="LILV",
max_length=4
)
destination = models.CharField(
null=False,
blank=False,
default="LILV",
max_length=4
)
time = models.DurationField(
null=False,
default=1
)
stop = models.BooleanField(
default=False
)
def __str__(self):
if self.stop:
return "Refuelling Stop"
else:
return f"Flight Leg: {self.departure} -> {self.destination}"
class Training(models.Model):
id = models.BigAutoField(
primary_key=True
)
weekpref = models.ForeignKey(
WeekPreference,
null=False,
on_delete=models.CASCADE
)
mission = models.ForeignKey(
MissionProfile,
null=True,
on_delete=models.CASCADE
)
monday = models.BooleanField(
default=True,
null=False
)
tuesday = models.BooleanField(
default=True,
null=False
)
wednesday = models.BooleanField(
default=True,
null=False
)
thursday = models.BooleanField(
default=True,
null=False
)
saturday = models.BooleanField(
default=True,
null=False
)
sunday = models.BooleanField(
default=True,
null=False
)
notes = models.TextField(
max_length=140,
null=True,
blank=True
)
def __str__(self):
return f"{self.mission}"

31
techdb/poetry.lock generated
View File

@@ -34,6 +34,24 @@ tzdata = {version = "*", markers = "sys_platform == \"win32\""}
argon2 = ["argon2-cffi (>=19.1.0)"]
bcrypt = ["bcrypt"]
[[package]]
name = "django-nested-admin"
version = "4.1.1"
description = "Django admin classes that allow for nested inlines"
optional = false
python-versions = ">=3.6"
files = [
{file = "django-nested-admin-4.1.1.tar.gz", hash = "sha256:645d63b38d579b034a65e0983f1f8cbb8824c75b4232f8d62a1583fa7a9f568f"},
{file = "django_nested_admin-4.1.1-py3-none-any.whl", hash = "sha256:7e72ab7a8ae4c91074f6f709ce38fdf54f9c5f78d19e68772e0f05b83090ec9f"},
]
[package.dependencies]
python-monkey-business = ">=1.0.0"
[package.extras]
dev = ["Pillow", "black", "dj-database-url", "django-selenosis", "flake8", "pytest", "pytest-cov", "pytest-django", "pytest-xdist", "selenium"]
test = ["Pillow", "dj-database-url", "django-selenosis", "pytest", "pytest-cov", "pytest-django", "pytest-xdist", "selenium"]
[[package]]
name = "psycopg2-binary"
version = "2.9.10"
@@ -110,6 +128,17 @@ files = [
{file = "psycopg2_binary-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5"},
]
[[package]]
name = "python-monkey-business"
version = "1.1.0"
description = "Utility functions for monkey-patching python code"
optional = false
python-versions = "*"
files = [
{file = "python-monkey-business-1.1.0.tar.gz", hash = "sha256:8393839cc741415ed5ddc2bd58e2d4ce07f966a7d26b7aebff19dcec64818edc"},
{file = "python_monkey_business-1.1.0-py2.py3-none-any.whl", hash = "sha256:15b4f603c749ba9a7b4f1acd36af023a6c5ba0f7e591c945f8253f0ef44bf389"},
]
[[package]]
name = "sqlparse"
version = "0.5.1"
@@ -139,4 +168,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = "^3.12"
content-hash = "c3b2acd3f06588e63224efb9ff8fc91a396c95e22862e40427c05b788901ea24"
content-hash = "17d19b9fd275a26e661d0db57222d91dd542a7a2f8a9106d79fd3eec4980ffb5"

View File

@@ -9,6 +9,7 @@ readme = "README.md"
python = "^3.12"
django = "^5.1.2"
psycopg2-binary = "^2.9.10"
django-nested-admin = "^4.1.1"
[build-system]

View File

@@ -37,6 +37,7 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'nested_admin',
'catops',
'flightslot'
]