From 91e6dd0cacb87398a5396438901c1e8e10458ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Tue, 29 Mar 2022 21:15:53 +0200 Subject: [PATCH] Extend functionalities --- dcc/dcc/utils.py | 9 +++++++ dcc/driver/views.py | 6 ++--- dcc/metadata/admin.py | 7 ++++- dcc/metadata/migrations/0004_equipment.py | 20 ++++++++++++++ .../migrations/0005_tag_delete_equipment.py | 27 +++++++++++++++++++ .../migrations/0006_alter_tag_options.py | 17 ++++++++++++ dcc/metadata/models.py | 16 ++++++++++- dcc/roster/admin.py | 7 ++--- .../0017_rename_cab_rollingstock.py | 18 +++++++++++++ .../0018_alter_rollingstock_options.py | 17 ++++++++++++ .../migrations/0019_rollingstock_tags.py | 19 +++++++++++++ ...ngstock_address_alter_rollingstock_tags.py | 24 +++++++++++++++++ .../0021_alter_rollingstock_tags.py | 19 +++++++++++++ .../0022_alter_rollingstock_address.py | 18 +++++++++++++ dcc/roster/models.py | 11 +++++--- dcc/roster/serializers.py | 6 ++--- dcc/roster/views.py | 20 +++++++------- 17 files changed, 237 insertions(+), 24 deletions(-) create mode 100644 dcc/metadata/migrations/0004_equipment.py create mode 100644 dcc/metadata/migrations/0005_tag_delete_equipment.py create mode 100644 dcc/metadata/migrations/0006_alter_tag_options.py create mode 100644 dcc/roster/migrations/0017_rename_cab_rollingstock.py create mode 100644 dcc/roster/migrations/0018_alter_rollingstock_options.py create mode 100644 dcc/roster/migrations/0019_rollingstock_tags.py create mode 100644 dcc/roster/migrations/0020_alter_rollingstock_address_alter_rollingstock_tags.py create mode 100644 dcc/roster/migrations/0021_alter_rollingstock_tags.py create mode 100644 dcc/roster/migrations/0022_alter_rollingstock_address.py diff --git a/dcc/dcc/utils.py b/dcc/dcc/utils.py index 1c3efea..a2b6f59 100644 --- a/dcc/dcc/utils.py +++ b/dcc/dcc/utils.py @@ -1,7 +1,16 @@ from django.utils.html import format_html +from django.utils.text import slugify as django_slugify def get_image_preview(url): return format_html( '' % url) + + +def slugify(string, custom_separator=None): + # Make slug 'flat', both '-' and '_' are replaced with '-' + string = django_slugify(string).replace('_', '-') + if custom_separator is not None: + string = string.replace('-', custom_separator) + return string diff --git a/dcc/driver/views.py b/dcc/driver/views.py index fa86425..d3477cc 100644 --- a/dcc/driver/views.py +++ b/dcc/driver/views.py @@ -8,7 +8,7 @@ from dcc.parsers import PlainTextParser from driver.connector import Connector from driver.serializers import ( FunctionSerializer, CabSerializer, InfraSerializer) -from roster.models import Cab as CabModel +from roster.models import RollingStock def addresschecker(f): @@ -17,8 +17,8 @@ def addresschecker(f): """ def addresslookup(request, address, *args): try: - CabModel.objects.get(address=address) - except CabModel.DoesNotExist: + RollingStock.objects.get(address=address) + except RollingStock.DoesNotExist: raise Http404 return f(request, address, *args) return addresslookup diff --git a/dcc/metadata/admin.py b/dcc/metadata/admin.py index 19430b7..8400565 100644 --- a/dcc/metadata/admin.py +++ b/dcc/metadata/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from metadata.models import Decoder, Manufacturer, Company +from metadata.models import Decoder, Manufacturer, Company, Tag @admin.register(Decoder) @@ -15,3 +15,8 @@ class CompanyAdmin(admin.ModelAdmin): @admin.register(Manufacturer) class ManufacturerAdmin(admin.ModelAdmin): readonly_fields = ('logo_thumbnail',) + + +@admin.register(Tag) +class TagAdmin(admin.ModelAdmin): + readonly_fields = ('slug',) diff --git a/dcc/metadata/migrations/0004_equipment.py b/dcc/metadata/migrations/0004_equipment.py new file mode 100644 index 0000000..2556ced --- /dev/null +++ b/dcc/metadata/migrations/0004_equipment.py @@ -0,0 +1,20 @@ +# Generated by Django 4.0.2 on 2022-03-06 19:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0003_metadata_extend'), + ] + + operations = [ + migrations.CreateModel( + name='Equipment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('equipment_type', models.CharField(max_length=128, unique=True)), + ], + ), + ] diff --git a/dcc/metadata/migrations/0005_tag_delete_equipment.py b/dcc/metadata/migrations/0005_tag_delete_equipment.py new file mode 100644 index 0000000..17e0a95 --- /dev/null +++ b/dcc/metadata/migrations/0005_tag_delete_equipment.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0.2 on 2022-03-06 20:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0004_equipment'), + ] + + operations = [ + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=128, unique=True)), + ('slug', models.CharField(max_length=128, unique=True)), + ], + options={ + 'verbose_name_plural': 'Equipment', + }, + ), + migrations.DeleteModel( + name='Equipment', + ), + ] diff --git a/dcc/metadata/migrations/0006_alter_tag_options.py b/dcc/metadata/migrations/0006_alter_tag_options.py new file mode 100644 index 0000000..dd833f5 --- /dev/null +++ b/dcc/metadata/migrations/0006_alter_tag_options.py @@ -0,0 +1,17 @@ +# Generated by Django 4.0.2 on 2022-03-06 20:15 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0005_tag_delete_equipment'), + ] + + operations = [ + migrations.AlterModelOptions( + name='tag', + options={}, + ), + ] diff --git a/dcc/metadata/models.py b/dcc/metadata/models.py index ca02885..38d51d2 100644 --- a/dcc/metadata/models.py +++ b/dcc/metadata/models.py @@ -1,7 +1,8 @@ from django.db import models +from django.dispatch.dispatcher import receiver from django_countries.fields import CountryField -from dcc.utils import get_image_preview +from dcc.utils import get_image_preview, slugify class Manufacturer(models.Model): @@ -67,3 +68,16 @@ class Decoder(models.Model): def image_thumbnail(self): return get_image_preview(self.image.url) image_thumbnail.short_description = "Preview" + + +class Tag(models.Model): + name = models.CharField(max_length=128, unique=True) + slug = models.CharField(max_length=128, unique=True) + + def __str__(self): + return self.name + + +@receiver(models.signals.pre_save, sender=Tag) +def tag_pre_save(sender, instance, **kwargs): + instance.slug = slugify(instance.name) diff --git a/dcc/roster/admin.py b/dcc/roster/admin.py index 5889b18..2b2ec13 100644 --- a/dcc/roster/admin.py +++ b/dcc/roster/admin.py @@ -1,9 +1,9 @@ from django.contrib import admin -from roster.models import Cab +from roster.models import RollingStock -@admin.register(Cab) -class CabAdmin(admin.ModelAdmin): +@admin.register(RollingStock) +class RollingStockAdmin(admin.ModelAdmin): readonly_fields = ('image_thumbnail', 'creation_time', 'updated_time',) list_display = ('identifier', 'address', 'manufacturer', 'company') list_filter = list_display @@ -12,6 +12,7 @@ class CabAdmin(admin.ModelAdmin): fieldsets = ( (None, { 'fields': ('identifier', + 'tags', 'address', 'manufacturer', 'decoder', diff --git a/dcc/roster/migrations/0017_rename_cab_rollingstock.py b/dcc/roster/migrations/0017_rename_cab_rollingstock.py new file mode 100644 index 0000000..be822e7 --- /dev/null +++ b/dcc/roster/migrations/0017_rename_cab_rollingstock.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2022-03-06 19:42 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0003_metadata_extend'), + ('roster', '0016_alter_cab_image'), + ] + + operations = [ + migrations.RenameModel( + old_name='Cab', + new_name='RollingStock', + ), + ] diff --git a/dcc/roster/migrations/0018_alter_rollingstock_options.py b/dcc/roster/migrations/0018_alter_rollingstock_options.py new file mode 100644 index 0000000..67d34fc --- /dev/null +++ b/dcc/roster/migrations/0018_alter_rollingstock_options.py @@ -0,0 +1,17 @@ +# Generated by Django 4.0.2 on 2022-03-06 19:50 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0017_rename_cab_rollingstock'), + ] + + operations = [ + migrations.AlterModelOptions( + name='rollingstock', + options={'ordering': ['address', 'identifier'], 'verbose_name_plural': 'Rolling stock'}, + ), + ] diff --git a/dcc/roster/migrations/0019_rollingstock_tags.py b/dcc/roster/migrations/0019_rollingstock_tags.py new file mode 100644 index 0000000..47d55e5 --- /dev/null +++ b/dcc/roster/migrations/0019_rollingstock_tags.py @@ -0,0 +1,19 @@ +# Generated by Django 4.0.2 on 2022-03-06 20:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0006_alter_tag_options'), + ('roster', '0018_alter_rollingstock_options'), + ] + + operations = [ + migrations.AddField( + model_name='rollingstock', + name='tags', + field=models.ManyToManyField(related_name='rolling_stock', to='metadata.Tag'), + ), + ] diff --git a/dcc/roster/migrations/0020_alter_rollingstock_address_alter_rollingstock_tags.py b/dcc/roster/migrations/0020_alter_rollingstock_address_alter_rollingstock_tags.py new file mode 100644 index 0000000..791e23b --- /dev/null +++ b/dcc/roster/migrations/0020_alter_rollingstock_address_alter_rollingstock_tags.py @@ -0,0 +1,24 @@ +# Generated by Django 4.0.2 on 2022-03-06 20:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0006_alter_tag_options'), + ('roster', '0019_rollingstock_tags'), + ] + + operations = [ + migrations.AlterField( + model_name='rollingstock', + name='address', + field=models.SmallIntegerField(default=3, null=True), + ), + migrations.AlterField( + model_name='rollingstock', + name='tags', + field=models.ManyToManyField(null=True, related_name='rolling_stock', to='metadata.Tag'), + ), + ] diff --git a/dcc/roster/migrations/0021_alter_rollingstock_tags.py b/dcc/roster/migrations/0021_alter_rollingstock_tags.py new file mode 100644 index 0000000..be09e3f --- /dev/null +++ b/dcc/roster/migrations/0021_alter_rollingstock_tags.py @@ -0,0 +1,19 @@ +# Generated by Django 4.0.2 on 2022-03-06 20:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('metadata', '0006_alter_tag_options'), + ('roster', '0020_alter_rollingstock_address_alter_rollingstock_tags'), + ] + + operations = [ + migrations.AlterField( + model_name='rollingstock', + name='tags', + field=models.ManyToManyField(blank=True, related_name='rolling_stock', to='metadata.Tag'), + ), + ] diff --git a/dcc/roster/migrations/0022_alter_rollingstock_address.py b/dcc/roster/migrations/0022_alter_rollingstock_address.py new file mode 100644 index 0000000..61eb8fa --- /dev/null +++ b/dcc/roster/migrations/0022_alter_rollingstock_address.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2022-03-06 20:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('roster', '0021_alter_rollingstock_tags'), + ] + + operations = [ + migrations.AlterField( + model_name='rollingstock', + name='address', + field=models.SmallIntegerField(blank=True, default=3, null=True), + ), + ] diff --git a/dcc/roster/models.py b/dcc/roster/models.py index ca82fc2..9374cbb 100644 --- a/dcc/roster/models.py +++ b/dcc/roster/models.py @@ -4,7 +4,7 @@ from django.db import models # from django.dispatch import receiver from dcc.utils import get_image_preview -from metadata.models import Manufacturer, Decoder, Company +from metadata.models import Manufacturer, Decoder, Company, Tag # class OverwriteMixin(FileSystemStorage): # def get_available_name(self, name, max_length): @@ -12,12 +12,16 @@ from metadata.models import Manufacturer, Decoder, Company # return name -class Cab(models.Model): +class RollingStock(models.Model): uuid = models.UUIDField( primary_key=True, default=uuid4, editable=False) identifier = models.CharField(max_length=128, unique=False) - address = models.SmallIntegerField(default=3) + tags = models.ManyToManyField( + Tag, + related_name='rolling_stock', + blank=True) + address = models.SmallIntegerField(default=3, null=True, blank=True) manufacturer = models.ForeignKey( Manufacturer, on_delete=models.CASCADE, null=True, blank=True) @@ -42,6 +46,7 @@ class Cab(models.Model): class Meta: ordering = ['address', 'identifier'] + verbose_name_plural = "Rolling stock" def __str__(self): return "{0} {1}".format(self.manufacturer, self.identifier) diff --git a/dcc/roster/serializers.py b/dcc/roster/serializers.py index 628972b..1d345ee 100644 --- a/dcc/roster/serializers.py +++ b/dcc/roster/serializers.py @@ -1,15 +1,15 @@ from rest_framework import serializers -from roster.models import Cab +from roster.models import RollingStock from metadata.serializers import ( ManufacturerSerializer, CompanySerializer, DecoderSerializer) -class CabSerializer(serializers.ModelSerializer): +class RollingStockSerializer(serializers.ModelSerializer): manufacturer = ManufacturerSerializer() decoder = DecoderSerializer() company = CompanySerializer() class Meta: - model = Cab + model = RollingStock fields = "__all__" read_only_fields = ("creation_time", "updated_time") diff --git a/dcc/roster/views.py b/dcc/roster/views.py index 4d9286e..8916c0a 100644 --- a/dcc/roster/views.py +++ b/dcc/roster/views.py @@ -1,27 +1,27 @@ from rest_framework.generics import ListAPIView, RetrieveAPIView -from roster.models import Cab -from roster.serializers import CabSerializer +from roster.models import RollingStock +from roster.serializers import RollingStockSerializer class RosterList(ListAPIView): - queryset = Cab.objects.all() - serializer_class = CabSerializer + queryset = RollingStock.objects.all() + serializer_class = RollingStockSerializer class RosterGet(RetrieveAPIView): - queryset = Cab.objects.all() - serializer_class = CabSerializer + queryset = RollingStock.objects.all() + serializer_class = RollingStockSerializer lookup_field = 'uuid' class RosterAddress(RetrieveAPIView): - queryset = Cab.objects.all() - serializer_class = CabSerializer + queryset = RollingStock.objects.all() + serializer_class = RollingStockSerializer lookup_field = 'address' class RosterIdentifier(RetrieveAPIView): - queryset = Cab.objects.all() - serializer_class = CabSerializer + queryset = RollingStock.objects.all() + serializer_class = RollingStockSerializer lookup_field = 'identifier'