From fd76b2df28db3f75fcdf05dfbd7e041286abd18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Wed, 30 Mar 2022 23:15:24 +0200 Subject: [PATCH] Refactor rolling stock --- dcc/dcc/settings.py | 5 ++ dcc/driver/views.py | 4 +- dcc/metadata/admin.py | 9 ++- .../migrations/0007_rollingstocktype.py | 20 ++++++ ..._rollingstocktype_type_cartype_and_more.py | 44 ++++++++++++ ...category_rollingstocktype_type_and_more.py | 51 ++++++++++++++ .../0010_alter_typecategory_category.py | 18 +++++ ...gstocktype_category_delete_typecategory.py | 21 ++++++ .../0012_alter_rollingstocktype_category.py | 18 +++++ dcc/metadata/models.py | 13 ++++ dcc/roster/admin.py | 49 +++++++++++-- ...ve_rollingstock_image_rollingstockimage.py | 38 +++++++++++ .../0024_alter_rollingstockimage_image.py | 18 +++++ ...lter_rollingstockimage_options_and_more.py | 21 ++++++ .../0026_rollingstockdocument_delete_image.py | 28 ++++++++ .../0027_alter_rollingstockdocument_file.py | 18 +++++ .../0028_rollingstockdocument_description.py | 18 +++++ .../migrations/0029_rollingstock_sku.py | 18 +++++ dcc/roster/migrations/0030_engine.py | 25 +++++++ .../migrations/0031_rollingstock_type.py | 20 ++++++ .../migrations/0032_alter_engine_options.py | 17 +++++ .../migrations/0033_car_equipment_other.py | 35 ++++++++++ ...tock_type_car_type_engine_type_and_more.py | 39 +++++++++++ dcc/roster/models.py | 68 +++++++++++++++++-- dcc/roster/views.py | 2 +- 25 files changed, 600 insertions(+), 17 deletions(-) create mode 100644 dcc/metadata/migrations/0007_rollingstocktype.py create mode 100644 dcc/metadata/migrations/0008_enginetype_remove_rollingstocktype_type_cartype_and_more.py create mode 100644 dcc/metadata/migrations/0009_typecategory_rollingstocktype_type_and_more.py create mode 100644 dcc/metadata/migrations/0010_alter_typecategory_category.py create mode 100644 dcc/metadata/migrations/0011_alter_rollingstocktype_category_delete_typecategory.py create mode 100644 dcc/metadata/migrations/0012_alter_rollingstocktype_category.py create mode 100644 dcc/roster/migrations/0023_image_remove_rollingstock_image_rollingstockimage.py create mode 100644 dcc/roster/migrations/0024_alter_rollingstockimage_image.py create mode 100644 dcc/roster/migrations/0025_alter_rollingstockimage_options_and_more.py create mode 100644 dcc/roster/migrations/0026_rollingstockdocument_delete_image.py create mode 100644 dcc/roster/migrations/0027_alter_rollingstockdocument_file.py create mode 100644 dcc/roster/migrations/0028_rollingstockdocument_description.py create mode 100644 dcc/roster/migrations/0029_rollingstock_sku.py create mode 100644 dcc/roster/migrations/0030_engine.py create mode 100644 dcc/roster/migrations/0031_rollingstock_type.py create mode 100644 dcc/roster/migrations/0032_alter_engine_options.py create mode 100644 dcc/roster/migrations/0033_car_equipment_other.py create mode 100644 dcc/roster/migrations/0034_remove_rollingstock_type_car_type_engine_type_and_more.py diff --git a/dcc/dcc/settings.py b/dcc/dcc/settings.py index 4daef69..6eaa721 100644 --- a/dcc/dcc/settings.py +++ b/dcc/dcc/settings.py @@ -134,3 +134,8 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' MEDIA_URL = 'media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') + +ROLLING_STOCK_TYPES = [ + ("engine", "Engine"), ("car", "Car"), + ("equipment", "Equipment"), ("other", "Other") +] diff --git a/dcc/driver/views.py b/dcc/driver/views.py index d3477cc..1b9236b 100644 --- a/dcc/driver/views.py +++ b/dcc/driver/views.py @@ -16,9 +16,7 @@ def addresschecker(f): Check if DCC address does exist in the database """ def addresslookup(request, address, *args): - try: - RollingStock.objects.get(address=address) - except RollingStock.DoesNotExist: + if not RollingStock.objects.filter(address=address): raise Http404 return f(request, address, *args) return addresslookup diff --git a/dcc/metadata/admin.py b/dcc/metadata/admin.py index 8400565..98bd15f 100644 --- a/dcc/metadata/admin.py +++ b/dcc/metadata/admin.py @@ -1,5 +1,6 @@ from django.contrib import admin -from metadata.models import Decoder, Manufacturer, Company, Tag +from metadata.models import ( + Decoder, Manufacturer, Company, Tag, RollingStockType) @admin.register(Decoder) @@ -20,3 +21,9 @@ class ManufacturerAdmin(admin.ModelAdmin): @admin.register(Tag) class TagAdmin(admin.ModelAdmin): readonly_fields = ('slug',) + + +@admin.register(RollingStockType) +class RollingStockTypeAdmin(admin.ModelAdmin): + list_display = ('type', 'category') + list_filter = list_display diff --git a/dcc/metadata/migrations/0007_rollingstocktype.py b/dcc/metadata/migrations/0007_rollingstocktype.py new file mode 100644 index 0000000..157a422 --- /dev/null +++ b/dcc/metadata/migrations/0007_rollingstocktype.py @@ -0,0 +1,20 @@ +# Generated by Django 4.0.2 on 2022-03-30 19:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0006_alter_tag_options'), + ] + + operations = [ + migrations.CreateModel( + name='RollingStockType', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(max_length=64, unique=True)), + ], + ), + ] diff --git a/dcc/metadata/migrations/0008_enginetype_remove_rollingstocktype_type_cartype_and_more.py b/dcc/metadata/migrations/0008_enginetype_remove_rollingstocktype_type_cartype_and_more.py new file mode 100644 index 0000000..324761a --- /dev/null +++ b/dcc/metadata/migrations/0008_enginetype_remove_rollingstocktype_type_cartype_and_more.py @@ -0,0 +1,44 @@ +# Generated by Django 4.0.2 on 2022-03-30 19:55 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0007_rollingstocktype'), + ] + + operations = [ + migrations.CreateModel( + name='EngineType', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(max_length=64, unique=True)), + ], + ), + migrations.RemoveField( + model_name='rollingstocktype', + name='type', + ), + migrations.CreateModel( + name='CarType', + fields=[ + ('enginetype_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='metadata.enginetype')), + ], + bases=('metadata.enginetype',), + ), + migrations.AddField( + model_name='rollingstocktype', + name='engine_type', + field=models.ForeignKey(default='0', on_delete=django.db.models.deletion.CASCADE, related_name='engine_type', to='metadata.enginetype'), + preserve_default=False, + ), + migrations.AddField( + model_name='rollingstocktype', + name='car_type', + field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, related_name='car_type', to='metadata.cartype'), + preserve_default=False, + ), + ] diff --git a/dcc/metadata/migrations/0009_typecategory_rollingstocktype_type_and_more.py b/dcc/metadata/migrations/0009_typecategory_rollingstocktype_type_and_more.py new file mode 100644 index 0000000..952a56d --- /dev/null +++ b/dcc/metadata/migrations/0009_typecategory_rollingstocktype_type_and_more.py @@ -0,0 +1,51 @@ +# Generated by Django 4.0.2 on 2022-03-30 20:01 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0008_enginetype_remove_rollingstocktype_type_cartype_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='TypeCategory', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('category', models.CharField(max_length=64, unique=True)), + ], + ), + migrations.AddField( + model_name='rollingstocktype', + name='type', + field=models.CharField(default='0', max_length=64), + preserve_default=False, + ), + migrations.AddField( + model_name='rollingstocktype', + name='category', + field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to='metadata.typecategory'), + preserve_default=False, + ), + migrations.AlterUniqueTogether( + name='rollingstocktype', + unique_together={('category', 'type')}, + ), + migrations.RemoveField( + model_name='rollingstocktype', + name='car_type', + ), + migrations.RemoveField( + model_name='rollingstocktype', + name='engine_type', + ), + migrations.DeleteModel( + name='CarType', + ), + migrations.DeleteModel( + name='EngineType', + ), + ] diff --git a/dcc/metadata/migrations/0010_alter_typecategory_category.py b/dcc/metadata/migrations/0010_alter_typecategory_category.py new file mode 100644 index 0000000..0797b59 --- /dev/null +++ b/dcc/metadata/migrations/0010_alter_typecategory_category.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2022-03-30 20:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0009_typecategory_rollingstocktype_type_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='typecategory', + name='category', + field=models.CharField(choices=[('engine', 'Engine'), ('car', 'Car')], max_length=64, unique=True), + ), + ] diff --git a/dcc/metadata/migrations/0011_alter_rollingstocktype_category_delete_typecategory.py b/dcc/metadata/migrations/0011_alter_rollingstocktype_category_delete_typecategory.py new file mode 100644 index 0000000..6fb1ccd --- /dev/null +++ b/dcc/metadata/migrations/0011_alter_rollingstocktype_category_delete_typecategory.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0.2 on 2022-03-30 20:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0010_alter_typecategory_category'), + ] + + operations = [ + migrations.AlterField( + model_name='rollingstocktype', + name='category', + field=models.CharField(choices=[('engine', 'Engine'), ('car', 'Car')], max_length=64, unique=True), + ), + migrations.DeleteModel( + name='TypeCategory', + ), + ] diff --git a/dcc/metadata/migrations/0012_alter_rollingstocktype_category.py b/dcc/metadata/migrations/0012_alter_rollingstocktype_category.py new file mode 100644 index 0000000..e553e06 --- /dev/null +++ b/dcc/metadata/migrations/0012_alter_rollingstocktype_category.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2022-03-30 20:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0011_alter_rollingstocktype_category_delete_typecategory'), + ] + + operations = [ + migrations.AlterField( + model_name='rollingstocktype', + name='category', + field=models.CharField(choices=[('engine', 'Engine'), ('car', 'Car'), ('equipment', 'Equipment'), ('other', 'Other')], max_length=64), + ), + ] diff --git a/dcc/metadata/models.py b/dcc/metadata/models.py index 38d51d2..5243bf4 100644 --- a/dcc/metadata/models.py +++ b/dcc/metadata/models.py @@ -1,4 +1,5 @@ from django.db import models +from django.conf import settings from django.dispatch.dispatcher import receiver from django_countries.fields import CountryField @@ -81,3 +82,15 @@ class Tag(models.Model): @receiver(models.signals.pre_save, sender=Tag) def tag_pre_save(sender, instance, **kwargs): instance.slug = slugify(instance.name) + + +class RollingStockType(models.Model): + type = models.CharField(max_length=64) + category = models.CharField( + max_length=64, choices=settings.ROLLING_STOCK_TYPES) + + class Meta(object): + unique_together = ('category', 'type') + + def __str__(self): + return "{0}".format(self.type) diff --git a/dcc/roster/admin.py b/dcc/roster/admin.py index 2b2ec13..40766c4 100644 --- a/dcc/roster/admin.py +++ b/dcc/roster/admin.py @@ -1,27 +1,42 @@ from django.contrib import admin -from roster.models import RollingStock +from roster.models import ( + RollingStock, RollingStockImage, RollingStockDocument, Engine, Car, + Equipment, Other) + + +class RollingStockDocInline(admin.TabularInline): + model = RollingStockDocument + min_num = 0 + extra = 0 + + +class RollingStockImageInline(admin.TabularInline): + model = RollingStockImage + min_num = 0 + extra = 0 + readonly_fields = ('image_thumbnail',) -@admin.register(RollingStock) class RollingStockAdmin(admin.ModelAdmin): - readonly_fields = ('image_thumbnail', 'creation_time', 'updated_time',) - list_display = ('identifier', 'address', 'manufacturer', 'company') + inlines = (RollingStockImageInline, RollingStockDocInline) + readonly_fields = ('creation_time', 'updated_time',) + list_display = ('identifier', 'manufacturer', 'sku', 'company') list_filter = list_display search_fields = list_display fieldsets = ( (None, { 'fields': ('identifier', + 'type', 'tags', - 'address', 'manufacturer', + 'sku', 'decoder', + 'address', 'company', 'epoch', 'production_year', 'purchase_date', - 'image', - 'image_thumbnail', 'notes') }), ('Audit', { @@ -29,3 +44,23 @@ class RollingStockAdmin(admin.ModelAdmin): 'fields': ('creation_time', 'updated_time',) }), ) + + +@admin.register(Engine) +class Engine(RollingStockAdmin): + list_display = ('identifier', 'address', 'manufacturer', 'sku', 'company') + + +@admin.register(Car) +class Car(RollingStockAdmin): + pass + + +@admin.register(Equipment) +class Equipment(RollingStockAdmin): + pass + + +@admin.register(Other) +class Other(RollingStockAdmin): + pass diff --git a/dcc/roster/migrations/0023_image_remove_rollingstock_image_rollingstockimage.py b/dcc/roster/migrations/0023_image_remove_rollingstock_image_rollingstockimage.py new file mode 100644 index 0000000..73d8139 --- /dev/null +++ b/dcc/roster/migrations/0023_image_remove_rollingstock_image_rollingstockimage.py @@ -0,0 +1,38 @@ +# Generated by Django 4.0.2 on 2022-03-29 19:38 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0022_alter_rollingstock_address'), + ] + + operations = [ + migrations.CreateModel( + name='Image', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('image', models.ImageField(blank=True, null=True, upload_to='images/')), + ], + ), + migrations.RemoveField( + model_name='rollingstock', + name='image', + ), + migrations.CreateModel( + name='RollingStockImage', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('order', models.PositiveIntegerField()), + ('image', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='roster.image')), + ('rolling_stock', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='roster.rollingstock')), + ], + options={ + 'ordering': ['order'], + 'unique_together': {('rolling_stock', 'image')}, + }, + ), + ] diff --git a/dcc/roster/migrations/0024_alter_rollingstockimage_image.py b/dcc/roster/migrations/0024_alter_rollingstockimage_image.py new file mode 100644 index 0000000..2f95735 --- /dev/null +++ b/dcc/roster/migrations/0024_alter_rollingstockimage_image.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2022-03-29 20:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0023_image_remove_rollingstock_image_rollingstockimage'), + ] + + operations = [ + migrations.AlterField( + model_name='rollingstockimage', + name='image', + field=models.ImageField(blank=True, null=True, upload_to='images/'), + ), + ] diff --git a/dcc/roster/migrations/0025_alter_rollingstockimage_options_and_more.py b/dcc/roster/migrations/0025_alter_rollingstockimage_options_and_more.py new file mode 100644 index 0000000..5575f1b --- /dev/null +++ b/dcc/roster/migrations/0025_alter_rollingstockimage_options_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0.2 on 2022-03-29 20:02 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0024_alter_rollingstockimage_image'), + ] + + operations = [ + migrations.AlterModelOptions( + name='rollingstockimage', + options={}, + ), + migrations.RemoveField( + model_name='rollingstockimage', + name='order', + ), + ] diff --git a/dcc/roster/migrations/0026_rollingstockdocument_delete_image.py b/dcc/roster/migrations/0026_rollingstockdocument_delete_image.py new file mode 100644 index 0000000..fc1dc30 --- /dev/null +++ b/dcc/roster/migrations/0026_rollingstockdocument_delete_image.py @@ -0,0 +1,28 @@ +# Generated by Django 4.0.2 on 2022-03-29 20:21 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0025_alter_rollingstockimage_options_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='RollingStockDocument', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('file', models.ImageField(blank=True, null=True, upload_to='files/')), + ('rolling_stock', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='roster.rollingstock')), + ], + options={ + 'unique_together': {('rolling_stock', 'file')}, + }, + ), + migrations.DeleteModel( + name='Image', + ), + ] diff --git a/dcc/roster/migrations/0027_alter_rollingstockdocument_file.py b/dcc/roster/migrations/0027_alter_rollingstockdocument_file.py new file mode 100644 index 0000000..7758f28 --- /dev/null +++ b/dcc/roster/migrations/0027_alter_rollingstockdocument_file.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2022-03-29 20:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0026_rollingstockdocument_delete_image'), + ] + + operations = [ + migrations.AlterField( + model_name='rollingstockdocument', + name='file', + field=models.FileField(blank=True, null=True, upload_to='files/'), + ), + ] diff --git a/dcc/roster/migrations/0028_rollingstockdocument_description.py b/dcc/roster/migrations/0028_rollingstockdocument_description.py new file mode 100644 index 0000000..01a657b --- /dev/null +++ b/dcc/roster/migrations/0028_rollingstockdocument_description.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2022-03-29 20:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0027_alter_rollingstockdocument_file'), + ] + + operations = [ + migrations.AddField( + model_name='rollingstockdocument', + name='description', + field=models.CharField(blank=True, max_length=128), + ), + ] diff --git a/dcc/roster/migrations/0029_rollingstock_sku.py b/dcc/roster/migrations/0029_rollingstock_sku.py new file mode 100644 index 0000000..96b769f --- /dev/null +++ b/dcc/roster/migrations/0029_rollingstock_sku.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2022-03-30 19:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0028_rollingstockdocument_description'), + ] + + operations = [ + migrations.AddField( + model_name='rollingstock', + name='sku', + field=models.CharField(blank=True, max_length=32), + ), + ] diff --git a/dcc/roster/migrations/0030_engine.py b/dcc/roster/migrations/0030_engine.py new file mode 100644 index 0000000..b78a13e --- /dev/null +++ b/dcc/roster/migrations/0030_engine.py @@ -0,0 +1,25 @@ +# Generated by Django 4.0.2 on 2022-03-30 19:40 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0029_rollingstock_sku'), + ] + + operations = [ + migrations.CreateModel( + name='Engine', + fields=[ + ('rollingstock_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='roster.rollingstock')), + ], + options={ + 'verbose_name_plural': 'Engines', + 'ordering': ['address', 'identifier'], + }, + bases=('roster.rollingstock',), + ), + ] diff --git a/dcc/roster/migrations/0031_rollingstock_type.py b/dcc/roster/migrations/0031_rollingstock_type.py new file mode 100644 index 0000000..cb7b3c7 --- /dev/null +++ b/dcc/roster/migrations/0031_rollingstock_type.py @@ -0,0 +1,20 @@ +# Generated by Django 4.0.2 on 2022-03-30 20:26 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0012_alter_rollingstocktype_category'), + ('roster', '0030_engine'), + ] + + operations = [ + migrations.AddField( + model_name='rollingstock', + name='type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='metadata.rollingstocktype'), + ), + ] diff --git a/dcc/roster/migrations/0032_alter_engine_options.py b/dcc/roster/migrations/0032_alter_engine_options.py new file mode 100644 index 0000000..c91b297 --- /dev/null +++ b/dcc/roster/migrations/0032_alter_engine_options.py @@ -0,0 +1,17 @@ +# Generated by Django 4.0.2 on 2022-03-30 20:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0031_rollingstock_type'), + ] + + operations = [ + migrations.AlterModelOptions( + name='engine', + options={}, + ), + ] diff --git a/dcc/roster/migrations/0033_car_equipment_other.py b/dcc/roster/migrations/0033_car_equipment_other.py new file mode 100644 index 0000000..a516acb --- /dev/null +++ b/dcc/roster/migrations/0033_car_equipment_other.py @@ -0,0 +1,35 @@ +# Generated by Django 4.0.2 on 2022-03-30 20:57 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0032_alter_engine_options'), + ] + + operations = [ + migrations.CreateModel( + name='Car', + fields=[ + ('rollingstock_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='roster.rollingstock')), + ], + bases=('roster.rollingstock',), + ), + migrations.CreateModel( + name='Equipment', + fields=[ + ('rollingstock_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='roster.rollingstock')), + ], + bases=('roster.rollingstock',), + ), + migrations.CreateModel( + name='Other', + fields=[ + ('rollingstock_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='roster.rollingstock')), + ], + bases=('roster.rollingstock',), + ), + ] diff --git a/dcc/roster/migrations/0034_remove_rollingstock_type_car_type_engine_type_and_more.py b/dcc/roster/migrations/0034_remove_rollingstock_type_car_type_engine_type_and_more.py new file mode 100644 index 0000000..2a799f2 --- /dev/null +++ b/dcc/roster/migrations/0034_remove_rollingstock_type_car_type_engine_type_and_more.py @@ -0,0 +1,39 @@ +# Generated by Django 4.0.2 on 2022-03-30 20:59 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0012_alter_rollingstocktype_category'), + ('roster', '0033_car_equipment_other'), + ] + + operations = [ + migrations.RemoveField( + model_name='rollingstock', + name='type', + ), + migrations.AddField( + model_name='car', + name='type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='metadata.rollingstocktype'), + ), + migrations.AddField( + model_name='engine', + name='type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='metadata.rollingstocktype'), + ), + migrations.AddField( + model_name='equipment', + name='type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='metadata.rollingstocktype'), + ), + migrations.AddField( + model_name='other', + name='type', + field=models.ForeignKey(blank=True, limit_choices_to={'category': 'roster.models'}, null=True, on_delete=django.db.models.deletion.CASCADE, to='metadata.rollingstocktype'), + ), + ] diff --git a/dcc/roster/models.py b/dcc/roster/models.py index 9374cbb..e641df8 100644 --- a/dcc/roster/models.py +++ b/dcc/roster/models.py @@ -1,10 +1,12 @@ +import os from uuid import uuid4 from django.db import models # from django.core.files.storage import FileSystemStorage # from django.dispatch import receiver from dcc.utils import get_image_preview -from metadata.models import Manufacturer, Decoder, Company, Tag +from metadata.models import ( + Manufacturer, Decoder, Company, Tag, RollingStockType) # class OverwriteMixin(FileSystemStorage): # def get_available_name(self, name, max_length): @@ -25,6 +27,7 @@ class RollingStock(models.Model): manufacturer = models.ForeignKey( Manufacturer, on_delete=models.CASCADE, null=True, blank=True) + sku = models.CharField(max_length=32, blank=True) decoder = models.ForeignKey( Decoder, on_delete=models.CASCADE, null=True, blank=True) @@ -35,10 +38,6 @@ class RollingStock(models.Model): production_year = models.SmallIntegerField(null=True, blank=True) purchase_date = models.DateField(null=True, blank=True) - image = models.ImageField( - upload_to='images/', - null=True, - blank=True) notes = models.TextField(blank=True) creation_time = models.DateTimeField(auto_now_add=True) @@ -51,10 +50,69 @@ class RollingStock(models.Model): def __str__(self): return "{0} {1}".format(self.manufacturer, self.identifier) + +class Engine(RollingStock): + type = models.ForeignKey( + RollingStockType, on_delete=models.CASCADE, + limit_choices_to={'category': 'engine'}, + null=True, blank=True) + + +class Car(RollingStock): + type = models.ForeignKey( + RollingStockType, on_delete=models.CASCADE, + limit_choices_to={'category': 'car'}, + null=True, blank=True) + + +class Equipment(RollingStock): + type = models.ForeignKey( + RollingStockType, on_delete=models.CASCADE, + limit_choices_to={'category': 'equipment'}, + null=True, blank=True) + + +class Other(RollingStock): + type = models.ForeignKey( + RollingStockType, on_delete=models.CASCADE, + limit_choices_to={'category': 'other'}, + null=True, blank=True) + + +class RollingStockDocument(models.Model): + rolling_stock = models.ForeignKey( + RollingStock, on_delete=models.CASCADE) + description = models.CharField(max_length=128, blank=True) + file = models.FileField( + upload_to='files/', + null=True, + blank=True) + + class Meta(object): + unique_together = ('rolling_stock', 'file') + + def __str__(self): + return "{0}".format(os.path.basename(self.file.name)) + # return "{0}".format(self.description) + + +class RollingStockImage(models.Model): + rolling_stock = models.ForeignKey( + RollingStock, on_delete=models.CASCADE) + image = models.ImageField( + upload_to='images/', + null=True, + blank=True) + def image_thumbnail(self): return get_image_preview(self.image.url) image_thumbnail.short_description = "Preview" + class Meta(object): + unique_together = ('rolling_stock', 'image') + + def __str__(self): + return "{0}".format(os.path.basename(self.image.name)) # @receiver(models.signals.post_delete, sender=Cab) # def post_save_image(sender, instance, *args, **kwargs): diff --git a/dcc/roster/views.py b/dcc/roster/views.py index 8916c0a..6a29409 100644 --- a/dcc/roster/views.py +++ b/dcc/roster/views.py @@ -15,7 +15,7 @@ class RosterGet(RetrieveAPIView): lookup_field = 'uuid' -class RosterAddress(RetrieveAPIView): +class RosterAddress(ListAPIView): queryset = RollingStock.objects.all() serializer_class = RollingStockSerializer lookup_field = 'address'