diff --git a/docs/changelog.rst b/docs/changelog.rst index e10b0e8b89..650dd1af10 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -14,6 +14,8 @@ CHANGELOG - Filter by multiple structures on Blades list (#3646) - Add a multiselect to filter the Blades by more than one manager - Filter by begin date by default on touristic events in APIv2 (#3597) +- Add model LinePictogram for each line (#3327) +- Add fixtures for LinePictogram (#3327) 2.99.0 (2023-07-18) ----------------------- diff --git a/docs/install/advanced-configuration.rst b/docs/install/advanced-configuration.rst index eb531d3013..218edf606e 100644 --- a/docs/install/advanced-configuration.rst +++ b/docs/install/advanced-configuration.rst @@ -1378,7 +1378,14 @@ Correspond to the format used in export of lines. Used in csv of signage. * *bladenumber is the number of the blade* * *linenumber is the number of the line* +If you want to add default pictograms of national parks, you can execute this command: +:: + + sudo geotrek loaddata /opt/geotrek-admin/lib/python*/site-packages/geotrek/signage/fixtures/pictograms_pn.json + cp /opt/geotrek-admin/lib/python*/site-packages/geotrek/signage/fixtures/upload/* /opt/geotrek-admin/var/media/upload/ + + **Screenshots** :: diff --git a/geotrek/signage/admin.py b/geotrek/signage/admin.py index 4e4efc0945..7043931ec2 100644 --- a/geotrek/signage/admin.py +++ b/geotrek/signage/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin from geotrek.common.mixins.actions import MergeActionMixin -from geotrek.signage.models import SignageType, Color, Sealing, Direction, BladeType +from geotrek.signage.models import LinePictogram, SignageType, Color, Sealing, Direction, BladeType class ColorBladeAdmin(MergeActionMixin, admin.ModelAdmin): @@ -14,6 +14,12 @@ class DirectionBladeAdmin(MergeActionMixin, admin.ModelAdmin): merge_field = 'label' +class LinePictogramAdmin(MergeActionMixin, admin.ModelAdmin): + search_fields = ('label',) + merge_field = 'label' + list_display = ('label', 'pictogram_img', 'code') + + class SealingAdmin(MergeActionMixin, admin.ModelAdmin): search_fields = ('label',) merge_field = 'label' @@ -127,3 +133,4 @@ def get_list_filter(self, request): admin.site.register(Sealing, SealingAdmin) admin.site.register(Direction, DirectionBladeAdmin) admin.site.register(BladeType, BladeTypeAdmin) +admin.site.register(LinePictogram, LinePictogramAdmin) diff --git a/geotrek/signage/fixtures/basic.json b/geotrek/signage/fixtures/basic.json index 0196f691c3..79cb0ad43d 100644 --- a/geotrek/signage/fixtures/basic.json +++ b/geotrek/signage/fixtures/basic.json @@ -107,15 +107,6 @@ "date_insert": "2014-02-12T11:21:48.961Z" } }, - { - "pk": 3, - "model": "signage.bladetype", - "fields": { - "label": "Directionnel", - "date_update": "2014-02-12T11:21:48.961Z", - "date_insert": "2014-02-12T11:21:48.961Z" - } - }, { "pk": 1, "model": "signage.color", diff --git a/geotrek/signage/fixtures/pictograms_pn.json b/geotrek/signage/fixtures/pictograms_pn.json new file mode 100644 index 0000000000..96bdad0306 --- /dev/null +++ b/geotrek/signage/fixtures/pictograms_pn.json @@ -0,0 +1,227 @@ +[ + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/011.svg", + "label": "No dogs, not even on leashes", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/012.svg", + "label": "No noise, no disturbance", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/021.svg", + "label": "No picking or taking", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/022.svg", + "label": "No guns", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/023.svg", + "label": "No fishing within fifty meters of the shoreline", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/031.svg", + "label": "No trash", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/033.svg", + "label": "No fire", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/034.svg", + "label": "No smoking", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/041.svg", + "label": "No camping", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/042.svg", + "label": "No tramping", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/043.svg", + "label": "Motorhomes prohibited", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/051.svg", + "label": "No car", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/052.svg", + "label": "No motorcycle", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/053.svg", + "label": "No off-road bike", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/054.svg", + "label": "No anchoring", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/055.svg", + "label": "No horseback riding activity", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/056.svg", + "label": "No hang-gliding or other air sports", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/057.svg", + "label": "No paragliding or other air sports", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/058.svg", + "label": "Stay on the paths", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/060.svg", + "label": "Do not collect minerals", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/061.svg", + "label": "Do not collect animals", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/069.svg", + "label": "Collecting turtles prohibited", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/070.svg", + "label": "No picking mushrooms", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/111.svg", + "label": "Dog on leash", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + }, + { + "model": "signage.linepictogram", + "fields": { + "pictogram": "upload/153.svg", + "label": "Camping from 7pm to 9am", + "date_update": "2023-08-08T15:35:12.189Z", + "date_insert": "2023-08-08T15:35:12.189Z" + } + } +] \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/011.svg b/geotrek/signage/fixtures/upload/011.svg new file mode 100644 index 0000000000..766ad91ee5 --- /dev/null +++ b/geotrek/signage/fixtures/upload/011.svg @@ -0,0 +1,75 @@ + + + +image/svg+xml + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/012.svg b/geotrek/signage/fixtures/upload/012.svg new file mode 100644 index 0000000000..f300f5fc2c --- /dev/null +++ b/geotrek/signage/fixtures/upload/012.svg @@ -0,0 +1,118 @@ + + + +image/svg+xml + + + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/021.svg b/geotrek/signage/fixtures/upload/021.svg new file mode 100644 index 0000000000..95840dc332 --- /dev/null +++ b/geotrek/signage/fixtures/upload/021.svg @@ -0,0 +1,141 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/022.svg b/geotrek/signage/fixtures/upload/022.svg new file mode 100644 index 0000000000..bc24068522 --- /dev/null +++ b/geotrek/signage/fixtures/upload/022.svg @@ -0,0 +1,75 @@ + + + +image/svg+xml + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/023.svg b/geotrek/signage/fixtures/upload/023.svg new file mode 100644 index 0000000000..eaec07389c --- /dev/null +++ b/geotrek/signage/fixtures/upload/023.svg @@ -0,0 +1,98 @@ + + + +image/svg+xml + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/031.svg b/geotrek/signage/fixtures/upload/031.svg new file mode 100644 index 0000000000..61debe91ab --- /dev/null +++ b/geotrek/signage/fixtures/upload/031.svg @@ -0,0 +1,139 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/033.svg b/geotrek/signage/fixtures/upload/033.svg new file mode 100644 index 0000000000..cedbeca2bd --- /dev/null +++ b/geotrek/signage/fixtures/upload/033.svg @@ -0,0 +1,91 @@ + + + +image/svg+xml + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/034.svg b/geotrek/signage/fixtures/upload/034.svg new file mode 100644 index 0000000000..af50b87479 --- /dev/null +++ b/geotrek/signage/fixtures/upload/034.svg @@ -0,0 +1,109 @@ + + + +image/svg+xml + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/041.svg b/geotrek/signage/fixtures/upload/041.svg new file mode 100644 index 0000000000..3cedd3718f --- /dev/null +++ b/geotrek/signage/fixtures/upload/041.svg @@ -0,0 +1,81 @@ + + + +image/svg+xml + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/042.svg b/geotrek/signage/fixtures/upload/042.svg new file mode 100644 index 0000000000..f2c64bae12 --- /dev/null +++ b/geotrek/signage/fixtures/upload/042.svg @@ -0,0 +1,125 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/043.svg b/geotrek/signage/fixtures/upload/043.svg new file mode 100644 index 0000000000..f85818d58a --- /dev/null +++ b/geotrek/signage/fixtures/upload/043.svg @@ -0,0 +1,105 @@ + + + +image/svg+xml + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/051.svg b/geotrek/signage/fixtures/upload/051.svg new file mode 100644 index 0000000000..ebfe90d814 --- /dev/null +++ b/geotrek/signage/fixtures/upload/051.svg @@ -0,0 +1,81 @@ + + + +image/svg+xml + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/052.svg b/geotrek/signage/fixtures/upload/052.svg new file mode 100644 index 0000000000..dc2032dfa6 --- /dev/null +++ b/geotrek/signage/fixtures/upload/052.svg @@ -0,0 +1,91 @@ + + + +image/svg+xml + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/053.svg b/geotrek/signage/fixtures/upload/053.svg new file mode 100644 index 0000000000..3bf484ab4b --- /dev/null +++ b/geotrek/signage/fixtures/upload/053.svg @@ -0,0 +1,109 @@ + + + +image/svg+xml + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/054.svg b/geotrek/signage/fixtures/upload/054.svg new file mode 100644 index 0000000000..26e72df734 --- /dev/null +++ b/geotrek/signage/fixtures/upload/054.svg @@ -0,0 +1,81 @@ + + + +image/svg+xml + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/055.svg b/geotrek/signage/fixtures/upload/055.svg new file mode 100644 index 0000000000..9aca65dae6 --- /dev/null +++ b/geotrek/signage/fixtures/upload/055.svg @@ -0,0 +1,81 @@ + + + +image/svg+xml + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/056.svg b/geotrek/signage/fixtures/upload/056.svg new file mode 100644 index 0000000000..2c2bb196b4 --- /dev/null +++ b/geotrek/signage/fixtures/upload/056.svg @@ -0,0 +1,87 @@ + + + +image/svg+xml + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/057.svg b/geotrek/signage/fixtures/upload/057.svg new file mode 100644 index 0000000000..fa1d84f5e1 --- /dev/null +++ b/geotrek/signage/fixtures/upload/057.svg @@ -0,0 +1,91 @@ + + + +image/svg+xml + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/058.svg b/geotrek/signage/fixtures/upload/058.svg new file mode 100644 index 0000000000..f805473975 --- /dev/null +++ b/geotrek/signage/fixtures/upload/058.svg @@ -0,0 +1,133 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/060.svg b/geotrek/signage/fixtures/upload/060.svg new file mode 100644 index 0000000000..ad6a74f3b0 --- /dev/null +++ b/geotrek/signage/fixtures/upload/060.svg @@ -0,0 +1,157 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/061.svg b/geotrek/signage/fixtures/upload/061.svg new file mode 100644 index 0000000000..2fb61c51df --- /dev/null +++ b/geotrek/signage/fixtures/upload/061.svg @@ -0,0 +1,173 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/069.svg b/geotrek/signage/fixtures/upload/069.svg new file mode 100644 index 0000000000..241cdcf8cf --- /dev/null +++ b/geotrek/signage/fixtures/upload/069.svg @@ -0,0 +1,182 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/070.svg b/geotrek/signage/fixtures/upload/070.svg new file mode 100644 index 0000000000..20b5bfe256 --- /dev/null +++ b/geotrek/signage/fixtures/upload/070.svg @@ -0,0 +1,141 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/geotrek/signage/fixtures/upload/111.svg b/geotrek/signage/fixtures/upload/111.svg new file mode 100644 index 0000000000..bdf3d22fa3 --- /dev/null +++ b/geotrek/signage/fixtures/upload/111.svg @@ -0,0 +1,80 @@ + + + +image/svg+xml + + + + + + + + \ No newline at end of file diff --git a/geotrek/signage/fixtures/upload/153.svg b/geotrek/signage/fixtures/upload/153.svg new file mode 100644 index 0000000000..b2f626d419 --- /dev/null +++ b/geotrek/signage/fixtures/upload/153.svg @@ -0,0 +1,115 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/geotrek/signage/forms.py b/geotrek/signage/forms.py index febb02650a..81deeddd48 100644 --- a/geotrek/signage/forms.py +++ b/geotrek/signage/forms.py @@ -23,7 +23,7 @@ class LineForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - fields_for_layout = ['id', 'number', 'direction', 'text', 'distance', 'pictogram_name', 'time'] + fields_for_layout = ['id', 'number', 'direction', 'text', 'distance', 'time', 'pictograms'] if not settings.DIRECTION_ON_LINES_ENABLED: del self.fields['direction'] @@ -34,7 +34,7 @@ def __init__(self, *args, **kwargs): self.helper.layout = Layout(*fields_for_layout) class Meta: - fields = ('id', 'blade', 'number', 'direction', 'text', 'distance', 'pictogram_name', 'time') + fields = ('id', 'blade', 'number', 'direction', 'text', 'distance', 'time', 'pictograms') LineFormset = inlineformset_factory(Blade, Line, form=LineForm, extra=1) diff --git a/geotrek/signage/locale/fr/LC_MESSAGES/django.po b/geotrek/signage/locale/fr/LC_MESSAGES/django.po index 339408f48c..e9f4f74195 100644 --- a/geotrek/signage/locale/fr/LC_MESSAGES/django.po +++ b/geotrek/signage/locale/fr/LC_MESSAGES/django.po @@ -169,4 +169,12 @@ msgid "meters" msgstr "mètres" msgid "Filter by one or more manager." -msgstr "Filtrer par un ou plusieurs gestionnaires" \ No newline at end of file +msgstr "Filtrer par un ou plusieurs gestionnaires" +msgid "Line pictograms" +msgstr "Pictogrammes des lignes" + +msgid "Line pictogram" +msgstr "Pictogramme des lignes" + +msgid "Pictograms" +msgstr "Pictogramme" diff --git a/geotrek/signage/migrations/0033_auto_20230807_0831.py b/geotrek/signage/migrations/0033_auto_20230807_0831.py new file mode 100644 index 0000000000..5bdf4dbe5e --- /dev/null +++ b/geotrek/signage/migrations/0033_auto_20230807_0831.py @@ -0,0 +1,34 @@ +# Generated by Django 3.2.20 on 2023-08-07 08:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('signage', '0032_alter_line_text'), + ] + + operations = [ + migrations.CreateModel( + name='LinePictogram', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date_insert', models.DateTimeField(auto_now_add=True, verbose_name='Insertion date')), + ('date_update', models.DateTimeField(auto_now=True, db_index=True, verbose_name='Update date')), + ('pictogram', models.FileField(blank=True, max_length=512, null=True, upload_to='upload', verbose_name='Pictogram')), + ('label', models.CharField(blank=True, default='', max_length=250, verbose_name='Label')), + ('code', models.CharField(blank=True, default='', max_length=250, verbose_name='Code')), + ('description', models.TextField(blank=True, help_text='Complete description', verbose_name='Description')), + ], + options={ + 'verbose_name': 'Line pictogram', + 'verbose_name_plural': 'Line pictograms', + }, + ), + migrations.AddField( + model_name='line', + name='pictograms', + field=models.ManyToManyField(blank=True, related_name='lines', to='signage.LinePictogram', verbose_name='Pictograms'), + ), + ] diff --git a/geotrek/signage/migrations/0034_migrate_pictogram.py b/geotrek/signage/migrations/0034_migrate_pictogram.py new file mode 100644 index 0000000000..7255230df9 --- /dev/null +++ b/geotrek/signage/migrations/0034_migrate_pictogram.py @@ -0,0 +1,21 @@ +from django.db import migrations + + +def migrate_pictogram(apps, schema_editor): + Line = apps.get_model('signage', 'Line') + LinePictogram = apps.get_model('signage', 'LinePictogram') + for line in Line.objects.all(): + if line.pictogram_name: + line_pictogram, created = LinePictogram.objects.get_or_create(label=line.pictogram_name) + line.pictograms.add(line_pictogram) + + +class Migration(migrations.Migration): + + dependencies = [ + ('signage', '0033_auto_20230807_0831'), + ] + + operations = [ + migrations.RunPython(migrate_pictogram, reverse_code=migrations.RunPython.noop), + ] diff --git a/geotrek/signage/migrations/0035_delete_pictogramname.py b/geotrek/signage/migrations/0035_delete_pictogramname.py new file mode 100644 index 0000000000..c9a3da83e4 --- /dev/null +++ b/geotrek/signage/migrations/0035_delete_pictogramname.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.16 on 2023-01-26 13:09 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('signage', '0034_migrate_pictogram'), + ] + + operations = [ + migrations.RemoveField( + model_name='line', + name='pictogram_name', + ), + ] diff --git a/geotrek/signage/models.py b/geotrek/signage/models.py index bb13fbd1a3..1abf226bc8 100755 --- a/geotrek/signage/models.py +++ b/geotrek/signage/models.py @@ -58,6 +58,16 @@ def get_pictogram_url(self): return os.path.join(settings.STATIC_URL, 'signage/picto-signage.png') +class LinePictogram(TimeStampedModelMixin, OptionalPictogramMixin): + label = models.CharField(verbose_name=_("Label"), max_length=250, blank=True, null=False, default='') + code = models.CharField(verbose_name=_("Code"), max_length=250, blank=True, null=False, default='') + description = models.TextField(verbose_name=_("Description"), blank=True, help_text=_("Complete description")) + + class Meta: + verbose_name = _("Line pictogram") + verbose_name_plural = _("Line pictograms") + + class Signage(GeotrekMapEntityMixin, BaseInfrastructure): """ An infrastructure in the park, which is of type SIGNAGE """ objects = SignageGISManager() @@ -326,8 +336,9 @@ class Line(models.Model): text = models.CharField(verbose_name=_("Text"), max_length=1000, blank=True, default="") distance = models.DecimalField(verbose_name=_("Distance"), null=True, blank=True, decimal_places=1, max_digits=8, help_text='km') - pictogram_name = models.CharField(verbose_name=_("Pictogram"), max_length=250, - blank=True, null=True) + pictograms = models.ManyToManyField('LinePictogram', related_name="lines", + blank=True, + verbose_name=_("Pictograms")) time = models.DurationField(verbose_name=pgettext_lazy("duration", "Time"), null=True, blank=True, help_text=_("Hours:Minutes:Seconds")) distance_pretty_verbose_name = _("Distance") diff --git a/geotrek/signage/templates/signage/blade_detail.html b/geotrek/signage/templates/signage/blade_detail.html index 31297ecbf4..18fb8d2c9e 100644 --- a/geotrek/signage/templates/signage/blade_detail.html +++ b/geotrek/signage/templates/signage/blade_detail.html @@ -61,7 +61,14 @@

{% trans "Lines" %}

{{ line }} {% if is_direction_on_lines_enabled %}{{ line.direction }}{% endif %} {{ line.text }} - {{ line.pictogram_name|default_if_none:"" }} + + {% for pictogram in line.pictograms.all %} + {{ pictogram.code|default_if_none:"" }} - + {{ pictogram.label|default_if_none:"" }} - + {{ pictogram.description|default_if_none:"" }} +
+ {% endfor %} + {{ line.distance_pretty }} {{ line.time_pretty }} diff --git a/geotrek/signage/templates/signage/blade_form.html b/geotrek/signage/templates/signage/blade_form.html index 0b40d52b64..c93ddbb2a4 100644 --- a/geotrek/signage/templates/signage/blade_form.html +++ b/geotrek/signage/templates/signage/blade_form.html @@ -24,6 +24,19 @@ {{ block.super }} {% endblock extrabody %} diff --git a/geotrek/signage/templates/signage/signage_detail_attributes.html b/geotrek/signage/templates/signage/signage_detail_attributes.html index 718761f6a3..0e29a8498b 100644 --- a/geotrek/signage/templates/signage/signage_detail_attributes.html +++ b/geotrek/signage/templates/signage/signage_detail_attributes.html @@ -114,7 +114,14 @@

{% trans "Blades" %}

{% endif %} {{ line.text }} - {{ line.pictogram_name|default_if_none:"" }} + + {% for pictogram in line.pictograms.all %} + {{ pictogram.label|default_if_none:"" }} + {{ pictogram.code|default_if_none:"" }} + {{ pictogram.description|default_if_none:"" }} +
+ {% endfor %} + {{ line.distance_pretty|default_if_none:"" }} {{ line.time_pretty|default_if_none:"" }} {% empty %} @@ -138,7 +145,14 @@

{% trans "Blades" %}

{% endif %} {{ line.direction|default_if_none:"" }} {{ line.text }} - {{ line.pictogram_name|default_if_none:"" }} + + {% for pictogram in line.pictograms.all %} + {{ pictogram.label|default_if_none:"" }} + {{ pictogram.code|default_if_none:"" }} + {{ pictogram.description|default_if_none:"" }} +
+ {% endfor %} + {{ line.distance_pretty|default_if_none:"" }} {{ line.time_pretty|default_if_none:"" }} {% empty %} diff --git a/geotrek/signage/tests/factories.py b/geotrek/signage/tests/factories.py index 8ef5594be3..bdfaf62a8b 100644 --- a/geotrek/signage/tests/factories.py +++ b/geotrek/signage/tests/factories.py @@ -96,6 +96,15 @@ def lines(obj, create, extracted=None, **kwargs): LineFactory.create(blade=obj) +class LinePictogramFactory(factory.django.DjangoModelFactory): + class Meta: + model = models.LinePictogram + + label = factory.Sequence(lambda n: "Label %s" % n) + code = factory.Sequence(lambda n: "Code %s" % n) + description = factory.Sequence(lambda n: "Description %s" % n) + + class LineFactory(factory.django.DjangoModelFactory): class Meta: model = models.Line @@ -104,6 +113,10 @@ class Meta: direction = factory.SubFactory(LineDirectionFactory) text = "Text" distance = 42.5 - pictogram_name = "Pictogram name" time = "0:42:30" blade = factory.SubFactory(BladeFactory) + + @factory.post_generation + def pictograms(obj, create, extracted=None, **kwargs): + if create: + obj.pictograms.add(LinePictogramFactory.create()) diff --git a/geotrek/signage/tests/test_views.py b/geotrek/signage/tests/test_views.py index a248b85f40..34b7eef8b7 100755 --- a/geotrek/signage/tests/test_views.py +++ b/geotrek/signage/tests/test_views.py @@ -220,9 +220,9 @@ def test_csv_format_with_lines(self): b"Direction,Condition," b"Coordinates (WGS 84 / Pseudo-Mercator)," b"Number 1,Text 1," - b"Distance 1,Time 1,Pictogram 1," + b"Distance 1,Time 1,Pictograms 1," b"Number 2,Text 2," - b"Distance 2,Time 2,Pictogram 2") + b"Distance 2,Time 2,Pictograms 2") def test_set_structure_with_permission(self): # The structure do not change because it changes with the signage form. diff --git a/geotrek/signage/views.py b/geotrek/signage/views.py index b6783e75ba..18726fad96 100755 --- a/geotrek/signage/views.py +++ b/geotrek/signage/views.py @@ -196,7 +196,7 @@ class BladeFormatList(MapEntityFormat, BladeList): mandatory_columns = ['id'] default_extra_columns = ['city', 'signage', 'printedelevation', 'bladecode', 'type', 'color', 'direction', 'condition', 'coordinates'] - columns_line = ['number', 'direction', 'text', 'distance_pretty', 'time_pretty', 'pictogram_name'] + columns_line = ['number', 'direction', 'text', 'distance_pretty', 'time_pretty', 'pictograms'] def csv_view(self, request, context, **kwargs): serializer = CSVBladeSerializer()