diff --git a/FlightGrid/settings.py b/FlightGrid/settings.py index c8c6c17..389d107 100644 --- a/FlightGrid/settings.py +++ b/FlightGrid/settings.py @@ -20,62 +20,63 @@ BASE_DIR = Path(__file__).resolve().parent.parent # See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-a_(p5k(2sgb(&ryzu9a+0yz_w+gi-z4o=0m7)kexf9k70k=+j$' +SECRET_KEY = "django-insecure-a_(p5k(2sgb(&ryzu9a+0yz_w+gi-z4o=0m7)kexf9k70k=+j$" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ["100.100.200.0"] # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "simulator", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = 'FlightGrid.urls' +ROOT_URLCONF = "FlightGrid.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'FlightGrid.wsgi.application' +WSGI_APPLICATION = "FlightGrid.wsgi.application" # Database # https://docs.djangoproject.com/en/5.2/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", } } @@ -85,16 +86,16 @@ DATABASES = { AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] @@ -102,9 +103,9 @@ AUTH_PASSWORD_VALIDATORS = [ # Internationalization # https://docs.djangoproject.com/en/5.2/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -114,9 +115,9 @@ USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.2/howto/static-files/ -STATIC_URL = 'static/' +STATIC_URL = "static/" # Default primary key field type # https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" diff --git a/requirements.txt b/requirements.txt index fd6d604..b62ee3c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,8 @@ asgiref==3.9.2 astroid==3.3.11 dill==0.4.0 Django==5.2.6 +django-stubs==5.2.5 +django-stubs-ext==5.2.5 dotenv==0.9.9 isort==6.0.1 mccabe==0.7.0 @@ -13,4 +15,7 @@ pylint==3.3.8 python-dotenv==1.1.1 sqlparse==0.5.3 tomlkit==0.13.3 +types-PyYAML==6.0.12.20250915 +types-requests==2.32.4.20250913 typing_extensions==4.15.0 +urllib3==2.5.0 diff --git a/simulator/admin.py b/simulator/admin.py index 8c38f3f..5b4a5b6 100644 --- a/simulator/admin.py +++ b/simulator/admin.py @@ -1,3 +1,8 @@ from django.contrib import admin - +from .models import Carrier, AircraftBase, Equipment, Aerodrome # Register your models here. + +admin.site.register(Carrier) +admin.site.register(AircraftBase) +admin.site.register(Equipment) +admin.site.register(Aerodrome) diff --git a/simulator/migrations/0001_initial.py b/simulator/migrations/0001_initial.py new file mode 100644 index 0000000..d73972a --- /dev/null +++ b/simulator/migrations/0001_initial.py @@ -0,0 +1,56 @@ +# Generated by Django 5.2.6 on 2025-09-30 02:02 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Aerodrome', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('icao', models.CharField(max_length=4, unique=True)), + ('iata', models.CharField(blank=True, max_length=3, null=True, unique=True)), + ('name', models.CharField(max_length=100)), + ('city', models.CharField(max_length=100)), + ('country', models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name='AircraftBase', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=20)), + ('manufacturer', models.CharField(max_length=50)), + ('range_nm', models.IntegerField()), + ('capacity', models.IntegerField()), + ('cruise_speed_kt', models.IntegerField()), + ], + ), + migrations.CreateModel( + name='Carrier', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('icao', models.CharField(max_length=3, unique=True)), + ('iata', models.CharField(max_length=2, unique=True)), + ('name', models.CharField(max_length=100, unique=True)), + ('country', models.CharField(max_length=30)), + ], + ), + migrations.CreateModel( + name='Equipment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('registration', models.CharField(max_length=10, unique=True)), + ('model', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aircraft', to='simulator.aircraftbase')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fleet', to='simulator.carrier')), + ], + ), + ] diff --git a/simulator/migrations/0002_alter_aerodrome_country.py b/simulator/migrations/0002_alter_aerodrome_country.py new file mode 100644 index 0000000..b57b10f --- /dev/null +++ b/simulator/migrations/0002_alter_aerodrome_country.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.6 on 2025-09-30 02:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('simulator', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='aerodrome', + name='country', + field=models.CharField(max_length=2), + ), + ] diff --git a/simulator/migrations/0003_alter_aerodrome_country.py b/simulator/migrations/0003_alter_aerodrome_country.py new file mode 100644 index 0000000..29bdcd0 --- /dev/null +++ b/simulator/migrations/0003_alter_aerodrome_country.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.6 on 2025-09-30 02:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('simulator', '0002_alter_aerodrome_country'), + ] + + operations = [ + migrations.AlterField( + model_name='aerodrome', + name='country', + field=models.CharField(max_length=3), + ), + ] diff --git a/simulator/models.py b/simulator/models.py deleted file mode 100644 index 71a8362..0000000 --- a/simulator/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/simulator/models/__init__.py b/simulator/models/__init__.py new file mode 100644 index 0000000..81a5a06 --- /dev/null +++ b/simulator/models/__init__.py @@ -0,0 +1,3 @@ +from .carrier import Carrier +from .aircraft import Equipment, AircraftBase +from .aerodrome import Aerodrome diff --git a/simulator/models/aerodrome.py b/simulator/models/aerodrome.py new file mode 100644 index 0000000..9042aed --- /dev/null +++ b/simulator/models/aerodrome.py @@ -0,0 +1,12 @@ +from django.db import models + + +class Aerodrome(models.Model): + icao = models.CharField(max_length=4, unique=True) + iata = models.CharField(max_length=3, unique=True, blank=True, null=True) + name = models.CharField(max_length=100) + city = models.CharField(max_length=100) + country = models.CharField(max_length=3) + + def __str__(self): + return f"{self.icao} - {self.city}" diff --git a/simulator/models/aircraft.py b/simulator/models/aircraft.py new file mode 100644 index 0000000..158fac4 --- /dev/null +++ b/simulator/models/aircraft.py @@ -0,0 +1,23 @@ +from django.db import models + + +class AircraftBase(models.Model): + name = models.CharField(max_length=20) + manufacturer = models.CharField(max_length=50) + range_nm = models.IntegerField() + capacity = models.IntegerField() + cruise_speed_kt = models.IntegerField() + + def __str__(self): + return f"{self.manufacturer} {self.name}" + + +class Equipment(models.Model): + registration = models.CharField(max_length=10, unique=True) + model = models.ForeignKey( + "AircraftBase", on_delete=models.CASCADE, related_name="aircraft" + ) + owner = models.ForeignKey("Carrier", on_delete=models.CASCADE, related_name="fleet") + + def __str__(self): + return f"{self.registration} ({self.model})" diff --git a/simulator/models/carrier.py b/simulator/models/carrier.py new file mode 100644 index 0000000..ce97225 --- /dev/null +++ b/simulator/models/carrier.py @@ -0,0 +1,15 @@ +from django.db import models +from .aircraft import Equipment + + +class Carrier(models.Model): + icao = models.CharField(max_length=3, unique=True) + iata = models.CharField(max_length=2, unique=True) + name = models.CharField(max_length=100, unique=True) + country = models.CharField(max_length=3) + + def __str__(self) -> str: + return f"{self.name} ({self.icao}/{self.iata})" + + def fleet_size(self) -> int: + return Equipment.objects.filter(owner=self).count()