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 from django.contrib import admin
import nested_admin
from .models import * from .models import *
# Register your models here. # Register your models here.
admin.site.register(Student, StudentAdmin) class HourBuildingLegInline(nested_admin.NestedTabularInline):
admin.site.register(MissionProfile) model = HourBuildingLeg
extra = 1
fk_name = 'hb'
class PreferenceInLIne(admin.TabularInline): class HourBuildingInLine(nested_admin.NestedTabularInline):
model = Preference model = HourBuilding
extra = 1
inlines = [HourBuildingLegInline]
fk_name = 'weekpref'
class TrainingInLIne(nested_admin.NestedTabularInline):
model = Training
extra = 0 extra = 0
fk_name = 'weekpref'
class WeekPreferenceAdmin(admin.ModelAdmin): class WeekPreferenceAdmin(nested_admin.NestedModelAdmin):
inlines = [PreferenceInLIne] 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) 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.db import models
from django.contrib import admin 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 _ from django.utils.translation import gettext_lazy as _
# Create your models here. # Create your models here.
class StudentAdmin(admin.ModelAdmin):
list_display = ("name", "surname", "email") class CourseTypes(models.TextChoices):
list_filter = [] 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): class Student(models.Model):
id = models.AutoField( id = models.AutoField(
@@ -28,44 +47,19 @@ class Student(models.Model):
max_length=32 max_length=32
) )
course = models.ForeignKey(
class MissionType(models.TextChoices): Course,
OTHER = "OTHER", _("OTHER") on_delete=models.DO_NOTHING,
HB = "HB", _("HB") null=True
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( active = models.BooleanField(
null=False, null=False,
default=MissionType.HB, default=True
choices=MissionType
)
mnum = models.PositiveSmallIntegerField(
null=True,
default=0
)
duration = models.DurationField(
null=False
) )
def __str__(self): def __str__(self):
if self.mtype is not MissionType.HB: return f"{self.surname} {self.name[0]}. - {self.course}"
return f"{self.mtype}_{self.mnum}"
class MissionProfileAdmin(admin.ModelAdmin):
list_display = ("mtype", "mnum")
class WeekPreference(models.Model): class WeekPreference(models.Model):
id = models.BigAutoField( id = models.BigAutoField(
@@ -75,7 +69,8 @@ class WeekPreference(models.Model):
week = models.PositiveSmallIntegerField( week = models.PositiveSmallIntegerField(
null=False, null=False,
db_index=True, db_index=True,
db_default=ExtractWeek(Now()) + 1 default=ExtractWeek(Now()) + 1,
auto_created=True
) )
student = models.ForeignKey( student = models.ForeignKey(
@@ -85,8 +80,59 @@ class WeekPreference(models.Model):
on_delete=models.DO_NOTHING 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( id = models.BigAutoField(
primary_key=True primary_key=True
) )
@@ -94,13 +140,12 @@ class Preference(models.Model):
weekpref = models.ForeignKey( weekpref = models.ForeignKey(
WeekPreference, WeekPreference,
null=False, null=False,
on_delete=models.DO_NOTHING on_delete=models.CASCADE
) )
mission = models.ForeignKey( aircraft = models.CharField(
MissionProfile, null=False,
null=True, choices=AircraftTypes
on_delete=models.DO_NOTHING
) )
monday = models.BooleanField( monday = models.BooleanField(
@@ -132,3 +177,104 @@ class Preference(models.Model):
default=True, default=True,
null=False 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)"] argon2 = ["argon2-cffi (>=19.1.0)"]
bcrypt = ["bcrypt"] 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]] [[package]]
name = "psycopg2-binary" name = "psycopg2-binary"
version = "2.9.10" version = "2.9.10"
@@ -110,6 +128,17 @@ files = [
{file = "psycopg2_binary-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5"}, {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]] [[package]]
name = "sqlparse" name = "sqlparse"
version = "0.5.1" version = "0.5.1"
@@ -139,4 +168,4 @@ files = [
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.12" python-versions = "^3.12"
content-hash = "c3b2acd3f06588e63224efb9ff8fc91a396c95e22862e40427c05b788901ea24" content-hash = "17d19b9fd275a26e661d0db57222d91dd542a7a2f8a9106d79fd3eec4980ffb5"

View File

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

View File

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