diff --git a/orgues/forms.py b/orgues/forms.py index eca3fd7..171d571 100644 --- a/orgues/forms.py +++ b/orgues/forms.py @@ -145,6 +145,7 @@ class Meta: "annee_fin", "circa", "type", + "provenance", "facteurs", "resume", ] diff --git a/orgues/migrations/0066_auto_20231101_1859.py b/orgues/migrations/0066_auto_20231101_1859.py new file mode 100644 index 0000000..5a2ef10 --- /dev/null +++ b/orgues/migrations/0066_auto_20231101_1859.py @@ -0,0 +1,37 @@ +# Generated by Django 3.1.14 on 2023-11-01 18:59 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('orgues', '0065_orgue_buffet_vide'), + ] + + operations = [ + migrations.CreateModel( + name='Localisation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('edifice', models.CharField(max_length=300)), + ('commune', models.CharField(max_length=100)), + ('departement', models.CharField(choices=[('Ain', 'Ain'), ('Aisne', 'Aisne'), ('Allier', 'Allier'), ('Alpes-de-Haute-Provence', 'Alpes-de-Haute-Provence'), ('Hautes-Alpes', 'Hautes-Alpes'), ('Alpes-Maritimes', 'Alpes-Maritimes'), ('Ardèche', 'Ardèche'), ('Ardennes', 'Ardennes'), ('Ariège', 'Ariège'), ('Aube', 'Aube'), ('Aude', 'Aude'), ('Aveyron', 'Aveyron'), ('Bouches-du-Rhône', 'Bouches-du-Rhône'), ('Calvados', 'Calvados'), ('Cantal', 'Cantal'), ('Charente', 'Charente'), ('Charente-Maritime', 'Charente-Maritime'), ('Cher', 'Cher'), ('Corrèze', 'Corrèze'), ('Corse-du-Sud', 'Corse-du-Sud'), ('Haute-Corse', 'Haute-Corse'), ("Côte-d'Or", "Côte-d'Or"), ("Côtes-d'Armor", "Côtes-d'Armor"), ('Creuse', 'Creuse'), ('Dordogne', 'Dordogne'), ('Doubs', 'Doubs'), ('Drôme', 'Drôme'), ('Eure', 'Eure'), ('Eure-et-Loir', 'Eure-et-Loir'), ('Finistère', 'Finistère'), ('Gard', 'Gard'), ('Haute-Garonne', 'Haute-Garonne'), ('Gers', 'Gers'), ('Gironde', 'Gironde'), ('Hérault', 'Hérault'), ('Ille-et-Vilaine', 'Ille-et-Vilaine'), ('Indre', 'Indre'), ('Indre-et-Loire', 'Indre-et-Loire'), ('Isère', 'Isère'), ('Jura', 'Jura'), ('Landes', 'Landes'), ('Loir-et-Cher', 'Loir-et-Cher'), ('Loire', 'Loire'), ('Haute-Loire', 'Haute-Loire'), ('Loire-Atlantique', 'Loire-Atlantique'), ('Loiret', 'Loiret'), ('Lot', 'Lot'), ('Lot-et-Garonne', 'Lot-et-Garonne'), ('Lozère', 'Lozère'), ('Maine-et-Loire', 'Maine-et-Loire'), ('Manche', 'Manche'), ('Marne', 'Marne'), ('Haute-Marne', 'Haute-Marne'), ('Mayenne', 'Mayenne'), ('Meurthe-et-Moselle', 'Meurthe-et-Moselle'), ('Meuse', 'Meuse'), ('Morbihan', 'Morbihan'), ('Moselle', 'Moselle'), ('Nièvre', 'Nièvre'), ('Nord', 'Nord'), ('Oise', 'Oise'), ('Orne', 'Orne'), ('Pas-de-Calais', 'Pas-de-Calais'), ('Puy-de-Dôme', 'Puy-de-Dôme'), ('Pyrénées-Atlantiques', 'Pyrénées-Atlantiques'), ('Hautes-Pyrénées', 'Hautes-Pyrénées'), ('Pyrénées-Orientales', 'Pyrénées-Orientales'), ('Bas-Rhin', 'Bas-Rhin'), ('Haut-Rhin', 'Haut-Rhin'), ('Rhône', 'Rhône'), ('Haute-Saône', 'Haute-Saône'), ('Saône-et-Loire', 'Saône-et-Loire'), ('Sarthe', 'Sarthe'), ('Savoie', 'Savoie'), ('Haute-Savoie', 'Haute-Savoie'), ('Paris', 'Paris'), ('Seine-Maritime', 'Seine-Maritime'), ('Seine-et-Marne', 'Seine-et-Marne'), ('Yvelines', 'Yvelines'), ('Deux-Sèvres', 'Deux-Sèvres'), ('Somme', 'Somme'), ('Tarn', 'Tarn'), ('Tarn-et-Garonne', 'Tarn-et-Garonne'), ('Var', 'Var'), ('Vaucluse', 'Vaucluse'), ('Vendée', 'Vendée'), ('Vienne', 'Vienne'), ('Haute-Vienne', 'Haute-Vienne'), ('Vosges', 'Vosges'), ('Yonne', 'Yonne'), ('Territoire de Belfort', 'Territoire de Belfort'), ('Essonne', 'Essonne'), ('Hauts-de-Seine', 'Hauts-de-Seine'), ('Seine-Saint-Denis', 'Seine-Saint-Denis'), ('Val-de-Marne', 'Val-de-Marne'), ("Val-d'Oise", "Val-d'Oise"), ('Guadeloupe', 'Guadeloupe'), ('Martinique', 'Martinique'), ('Mayotte', 'Mayotte'), ('Guyane', 'Guyane'), ('La Réunion', 'La Réunion'), ('Saint-Pierre-et-Miquelon', 'Saint-Pierre-et-Miquelon'), ('Nouvelle-Calédonie', 'Nouvelle-Calédonie')], max_length=50, verbose_name='Département')), + ('code_departement', models.CharField(choices=[('01', '01'), ('02', '02'), ('03', '03'), ('04', '04'), ('05', '05'), ('06', '06'), ('07', '07'), ('08', '08'), ('09', '09'), ('10', '10'), ('11', '11'), ('12', '12'), ('13', '13'), ('14', '14'), ('15', '15'), ('16', '16'), ('17', '17'), ('18', '18'), ('19', '19'), ('2A', '2A'), ('2B', '2B'), ('21', '21'), ('22', '22'), ('23', '23'), ('24', '24'), ('25', '25'), ('26', '26'), ('27', '27'), ('28', '28'), ('29', '29'), ('30', '30'), ('31', '31'), ('32', '32'), ('33', '33'), ('34', '34'), ('35', '35'), ('36', '36'), ('37', '37'), ('38', '38'), ('39', '39'), ('40', '40'), ('41', '41'), ('42', '42'), ('43', '43'), ('44', '44'), ('45', '45'), ('46', '46'), ('47', '47'), ('48', '48'), ('49', '49'), ('50', '50'), ('51', '51'), ('52', '52'), ('53', '53'), ('54', '54'), ('55', '55'), ('56', '56'), ('57', '57'), ('58', '58'), ('59', '59'), ('60', '60'), ('61', '61'), ('62', '62'), ('63', '63'), ('64', '64'), ('65', '65'), ('66', '66'), ('67', '67'), ('68', '68'), ('69', '69'), ('70', '70'), ('71', '71'), ('72', '72'), ('73', '73'), ('74', '74'), ('75', '75'), ('76', '76'), ('77', '77'), ('78', '78'), ('79', '79'), ('80', '80'), ('81', '81'), ('82', '82'), ('83', '83'), ('84', '84'), ('85', '85'), ('86', '86'), ('87', '87'), ('88', '88'), ('89', '89'), ('90', '90'), ('91', '91'), ('92', '92'), ('93', '93'), ('94', '94'), ('95', '95'), ('971', '971'), ('972', '972'), ('976', '976'), ('973', '973'), ('974', '974'), ('975', '975'), ('988', '988')], max_length=3, verbose_name='Code département')), + ('region', models.CharField(choices=[('Auvergne-Rhône-Alpes', 'Auvergne-Rhône-Alpes'), ('Bourgogne-Franche-Comté', 'Bourgogne-Franche-Comté'), ('Bretagne', 'Bretagne'), ('Centre-Val de Loire', 'Centre-Val de Loire'), ('Corse', 'Corse'), ('Grand Est', 'Grand Est'), ('Guadeloupe', 'Guadeloupe'), ('Guyane', 'Guyane'), ('Hauts-de-France', 'Hauts-de-France'), ('Île-de-France', 'Île-de-France'), ('La Réunion', 'La Réunion'), ('Martinique', 'Martinique'), ('Normandie', 'Normandie'), ('Nouvelle-Aquitaine', 'Nouvelle-Aquitaine'), ('Nouvelle-Calédonie', 'Nouvelle-Calédonie'), ('Occitanie', 'Occitanie'), ('Pays de la Loire', 'Pays de la Loire'), ("Provence-Alpes-Côte d'Azur", "Provence-Alpes-Côte d'Azur"), ('Saint-Pierre-et-Miquelon', 'Saint-Pierre-et-Miquelon')], max_length=50, verbose_name='Région')), + ('osm_type', models.CharField(blank=True, choices=[('node', 'Nœud (Node)'), ('way', 'Chemin (Way)'), ('relation', 'Relation (Relation)')], default='way', help_text="Type OSM de l'objet représenant l'édifice.", max_length=20, null=True, verbose_name='Type OpenStreetMap')), + ('osm_id', models.CharField(blank=True, help_text="Identifiant OSM de l'objet décrivant l'édifice.", max_length=20, null=True, verbose_name='Id OpenStreetMap')), + ], + ), + migrations.AlterField( + model_name='orgue', + name='buffet_vide', + field=models.BooleanField(default=False, verbose_name='Buffet vide'), + ), + migrations.AddField( + model_name='evenement', + name='localisation', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='orgues.localisation', verbose_name='Ancienne localisation'), + ), + ] diff --git a/orgues/migrations/0067_auto_20231103_1430.py b/orgues/migrations/0067_auto_20231103_1430.py new file mode 100644 index 0000000..da6aef2 --- /dev/null +++ b/orgues/migrations/0067_auto_20231103_1430.py @@ -0,0 +1,27 @@ +# Generated by Django 3.1.14 on 2023-11-03 14:30 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('orgues', '0066_auto_20231101_1859'), + ] + + operations = [ + migrations.RenameModel( + old_name='Localisation', + new_name='Provenance', + ), + migrations.RemoveField( + model_name='evenement', + name='localisation', + ), + migrations.AddField( + model_name='evenement', + name='provenance', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='orgues.provenance', verbose_name='Provenance'), + ), + ] diff --git a/orgues/models.py b/orgues/models.py index 5966e52..c005bdb 100644 --- a/orgues/models.py +++ b/orgues/models.py @@ -19,6 +19,8 @@ from accounts.models import User + + class Facteur(models.Model): """ Pas celui qui distribue le courrier @@ -36,65 +38,7 @@ class Meta: class Orgue(models.Model): - CHOIX_TYPE_OSM = ( - ("node", "Nœud (Node)"), - ("way", "Chemin (Way)"), - ("relation", "Relation (Relation)"), - ) - - CHOIX_PROPRIETAIRE = ( - ("commune", "Commune"), - ("interco", "Intercommunalité"), - ("etat", "Etat"), - ("association_culturelle", "Association culturelle"), - ("diocese", "Diocèse"), - ("paroisse", "Paroisse"), - ("congregation", "Congrégation"), - ("etablissement_scolaire", "Etablissement scolaire"), - ("conservatoire", "Conservatoire ou Ecole de musique"), - ("hopital", "Hôpital"), - ("particulier", "Particulier (propriété privée)"), - ) - - CHOIX_ETAT = ( - ('tres_bon', "Très bon, tout à fait jouable"), - ('bon', "Bon : jouable, défauts mineurs"), - ('altere', "Altéré : difficilement jouable"), - ('degrade', "Dégradé ou en ruine : injouable"), - ('restauration', "En restauration (ou projet initié)"), - ('disparu', 'Disparu') - ) - - CHOIX_QUALIFICATION_PALISSY = ( - ('orgue_de_tribune', 'orgue de tribune'), - ('orgue_de_choeur', 'orgue de choeur'), - ('orgue_a_cylindres', 'orgue à cylindres'), - ('orgue_a_manivelle', 'orgue à manivelle'), - ('orgue_de_triforium', 'orgue de triforium'), - ('orgue_portatif', 'orgue portatif'), - ('orgue_de_cabinet / salon', 'orgue de cabinet / salon'), - ) - CHOIX_TRANSMISSION = ( - ("mecanique", "Mécanique"), - ("mecanique_suspendue", "Mécanique suspendue"), - ("mecanique_balanciers", "Mécanique à balanciers"), - ("mecanique_barker", "Mécanique Barker"), - ("numerique", "Numérique"), - ("electrique", "Electrique"), - ("electrique_proportionnelle", "Electrique proportionnelle"), - ("electro_pneumatique", "Electro-pneumatique"), - ("pneumatique", "Pneumatique"), - ) - - CHOIX_TIRAGE = ( - ("mecanique", "Mécanique"), - ("pneumatique_haute_pression", "Pneumatique haute pression"), - ("pneumatique_basse_pression", "Pneumatique basse pression"), - ("numerique", "Numérique"), - ("electrique", "Electrique"), - ("electro_pneumatique", "Electro-pneumatique"), - ) - + CHOIX_REGION = ( ('Auvergne-Rhône-Alpes', 'Auvergne-Rhône-Alpes'), ('Bourgogne-Franche-Comté', 'Bourgogne-Franche-Comté'), @@ -221,9 +165,68 @@ class Orgue(models.Model): ('974', 'La Réunion'), ('975', 'Saint-Pierre-et-Miquelon'), ('988', 'Nouvelle-Calédonie'), + ) + CHOIX_TYPE_OSM = ( + ("node", "Nœud (Node)"), + ("way", "Chemin (Way)"), + ("relation", "Relation (Relation)"), ) + CHOIX_PROPRIETAIRE = ( + ("commune", "Commune"), + ("interco", "Intercommunalité"), + ("etat", "Etat"), + ("association_culturelle", "Association culturelle"), + ("diocese", "Diocèse"), + ("paroisse", "Paroisse"), + ("congregation", "Congrégation"), + ("etablissement_scolaire", "Etablissement scolaire"), + ("conservatoire", "Conservatoire ou Ecole de musique"), + ("hopital", "Hôpital"), + ("particulier", "Particulier (propriété privée)"), + ) + + CHOIX_ETAT = ( + ('tres_bon', "Très bon, tout à fait jouable"), + ('bon', "Bon : jouable, défauts mineurs"), + ('altere', "Altéré : difficilement jouable"), + ('degrade', "Dégradé ou en ruine : injouable"), + ('restauration', "En restauration (ou projet initié)") + ) + + CHOIX_QUALIFICATION_PALISSY = ( + ('orgue_de_tribune', 'orgue de tribune'), + ('orgue_de_choeur', 'orgue de choeur'), + ('orgue_a_cylindres', 'orgue à cylindres'), + ('orgue_a_manivelle', 'orgue à manivelle'), + ('orgue_de_triforium', 'orgue de triforium'), + ('orgue_portatif', 'orgue portatif'), + ('orgue_de_cabinet / salon', 'orgue de cabinet / salon'), + ) + CHOIX_TRANSMISSION = ( + ("mecanique", "Mécanique"), + ("mecanique_suspendue", "Mécanique suspendue"), + ("mecanique_balanciers", "Mécanique à balanciers"), + ("mecanique_barker", "Mécanique Barker"), + ("numerique", "Numérique"), + ("electrique", "Electrique"), + ("electrique_proportionnelle", "Electrique proportionnelle"), + ("electro_pneumatique", "Electro-pneumatique"), + ("pneumatique", "Pneumatique"), + ) + + CHOIX_TIRAGE = ( + ("mecanique", "Mécanique"), + ("pneumatique_haute_pression", "Pneumatique haute pression"), + ("pneumatique_basse_pression", "Pneumatique basse pression"), + ("numerique", "Numérique"), + ("electrique", "Electrique"), + ("electro_pneumatique", "Electro-pneumatique"), + ) + + + # Informations générales designation = models.CharField(max_length=300, null=True, verbose_name="Désignation de l'orgue", default="orgue", blank=True, help_text="Type d'orgue : grand orgue, orgue coffre, orgue portatif, etc.") @@ -688,6 +691,23 @@ class Meta: verbose_name = "Plan sonore" +class Provenance(models.Model): + edifice = models.CharField(max_length=300) + commune = models.CharField(max_length=100) + departement = models.CharField(verbose_name="Département", choices=[(c[1], c[1]) for c in Orgue.CHOIX_DEPARTEMENT], + max_length=50) + code_departement = models.CharField(choices=[(c[0], c[0]) for c in Orgue.CHOIX_DEPARTEMENT], + verbose_name="Code département", max_length=3) + region = models.CharField(verbose_name="Région", choices=Orgue.CHOIX_REGION, max_length=50) + osm_type = models.CharField(choices=Orgue.CHOIX_TYPE_OSM, verbose_name="Type OpenStreetMap", max_length=20, null=True, + blank=True, help_text="Type OSM de l'objet représenant l'édifice.", default="way") + osm_id = models.CharField(verbose_name="Id OpenStreetMap", max_length=20, null=True, blank=True, + help_text="Identifiant OSM de l'objet décrivant l'édifice.") + + def __str__(self): + return "{}, {}, {}".format(self.edifice, self.commune, self.departement) + + class Evenement(models.Model): """ Décrit les différents événements relatifs à un orgue @@ -722,6 +742,7 @@ class Evenement(models.Model): annee = models.IntegerField(verbose_name="Année de début de l'évènement") annee_fin = models.IntegerField(verbose_name="Année de fin de l'évènement", null=True, blank=True, help_text="Optionnelle") + provenance = models.ForeignKey(Provenance, on_delete=models.CASCADE, blank=True, null=True, verbose_name="Provenance") circa = models.BooleanField(default=False, verbose_name="Cocher si dates approximatives") type = models.CharField(max_length=20, choices=CHOIX_TYPE) facteurs = models.ManyToManyField(Facteur, blank=True, related_name="evenements") diff --git a/orgues/templates/orgues/evenement_form.html b/orgues/templates/orgues/evenement_form.html index 6284544..8b633f5 100644 --- a/orgues/templates/orgues/evenement_form.html +++ b/orgues/templates/orgues/evenement_form.html @@ -9,7 +9,32 @@ {% block js_extra_2 %} {% include 'orgues/facteur_create_modal.html' %} + {% include 'orgues/provenance_create_modal.html' %} {% endblock %} diff --git a/orgues/templates/orgues/orgue_detail.html b/orgues/templates/orgues/orgue_detail.html index e54b209..2660f9c 100644 --- a/orgues/templates/orgues/orgue_detail.html +++ b/orgues/templates/orgues/orgue_detail.html @@ -403,7 +403,7 @@

Sources

"display_date": "{{evenement.dates}}", "text": { "headline": "{{ evenement.get_type_display }}", - "text": "{% if evenement.resume %}{{ evenement.resume|linebreaksbr|safe|escapejs}}{% endif %}{% if evenement.facteurs.count %}

Facteur(s) : {{ evenement.facteurs.all|join:', ' }}

{% endif %}" + "text": "{% if evenement.resume %}{{ evenement.resume|linebreaksbr|safe|escapejs}}{% endif %}{% if evenement.facteurs.count %}

Facteur(s) : {{ evenement.facteurs.all|join:', ' }}

{% endif %} {% if evenement.type == 'deplacement' and evenement.provenance.osm_id and evenement.provenance.osm_type %} {% with 'https://www.openstreetmap.org/'|add:evenement.provenance.osm_type|add:'/'|add:evenement.provenance.osm_id as lien_osm %}

Provenance : {{ evenement.provenance }}

{% endwith %} {% endif %}" } }, {% endfor %} diff --git a/orgues/templates/orgues/provenance_create_modal.html b/orgues/templates/orgues/provenance_create_modal.html new file mode 100644 index 0000000..ff7f481 --- /dev/null +++ b/orgues/templates/orgues/provenance_create_modal.html @@ -0,0 +1,100 @@ + + +{% block js_extra_2 %} + +{% endblock %} \ No newline at end of file diff --git a/orgues/urls.py b/orgues/urls.py index 79f3ad7..2856ad0 100644 --- a/orgues/urls.py +++ b/orgues/urls.py @@ -32,6 +32,7 @@ path('evenement/edition//', v.EvenementUpdate.as_view(), name='evenement-update'), path('evenement/creation//', v.EvenementCreate.as_view(), name='evenement-create'), path('evenement/suppression//', v.EvenementDelete.as_view(), name='evenement-delete'), + path('provenance/creation/', v.ProvenanceCreateJS.as_view(), name='provenance-create-js'), # claviers path('clavier/creation//', v.ClavierCreate.as_view(), name='clavier-create'), diff --git a/orgues/views.py b/orgues/views.py index e94418b..5c8047e 100644 --- a/orgues/views.py +++ b/orgues/views.py @@ -34,7 +34,7 @@ from project import settings -from .models import Orgue, Clavier, Jeu, Evenement, Facteur, TypeJeu, Fichier, Image, Source, Contribution +from .models import Orgue, Clavier, Jeu, Evenement, Facteur, TypeJeu, Fichier, Image, Source, Contribution, Provenance import orgues.utilsorgues.correcteurorgues as co import orgues.utilsorgues.codification as codif import orgues.utilsorgues.code_geographique as codegeo @@ -1034,6 +1034,27 @@ def post(self, request, *args, **kwargs): return JsonResponse({'success': "false"}) +class ProvenanceCreateJS(FabCreateViewJS): + """ + Création d'une nouvelle Provenance. + Vue appelée par du code javascript + """ + model = Provenance + permission_required = "orgues.add_evenement" + fields = "__all__" + + def post(self, request, *args, **kwargs): + edifice = request.POST.get("edifice") + commune = request.POST.get("commune") + osm_type = request.POST.get("type_osm") + osm_id = request.POST.get("id_osm") + commune, departement, code_departement, region, code_insee = co.geographie_administrative(commune) + provenance, created = Provenance.objects.get_or_create(edifice=edifice, commune=commune, departement=departement, region=region, osm_type=osm_type, osm_id=osm_id) + + return JsonResponse( + {'success': "true", 'provenance': {'id': provenance.id, 'nom': provenance.__str__()}}) + + class FichierList(FabListView): """ Liste des facteurs