diff --git a/geotrek/tourism/forms.py b/geotrek/tourism/forms.py
index a92670a311..cf5aef6169 100644
--- a/geotrek/tourism/forms.py
+++ b/geotrek/tourism/forms.py
@@ -4,9 +4,11 @@
from geotrek.tourism.widgets import AutoLocateMapWidget
from crispy_forms.layout import Div, HTML, Fieldset
+from mapentity.widgets import SelectMultipleWithPop
+
from .models import (TouristicContent, TouristicEvent, TouristicEventParticipantCount,
- TouristicEventParticipantCategory)
+ TouristicEventParticipantCategory, TouristicEventOrganizer)
from geotrek.common.forms import CommonForm
@@ -142,6 +144,11 @@ def __init__(self, *args, **kwargs):
self.fields['end_date'].widget.attrs['placeholder'] = _('dd/mm/yyyy')
self.fields['start_time'].widget.attrs['placeholder'] = _('HH:MM')
self.fields['end_time'].widget.attrs['placeholder'] = _('HH:MM')
+ if self.user.has_perm("tourism.add_touristiceventorganizer"):
+ self.fields['organizer'].widget = SelectMultipleWithPop(
+ choices=self.fields['organizer'].choices,
+ add_url=TouristicEventOrganizer.get_add_url()
+ )
# Since we use chosen() in trek_form.html, we don't need the default help text
for f in ['themes', 'source']:
self.fields[f].help_text = ''
@@ -189,3 +196,9 @@ def _save_m2m(self):
TouristicEventParticipantCount.objects.update_or_create(event=self.instance, category=category, defaults={'count': count})
else:
TouristicEventParticipantCount.objects.filter(event=self.instance, category=category).delete()
+
+
+class TouristicEventOrganizerFormPopup(CommonForm):
+ class Meta:
+ model = TouristicEventOrganizer
+ fields = ['label']
diff --git a/geotrek/tourism/models.py b/geotrek/tourism/models.py
index 5b685ba716..5af120e49a 100644
--- a/geotrek/tourism/models.py
+++ b/geotrek/tourism/models.py
@@ -11,6 +11,7 @@
from django.dispatch import receiver
from django.utils.formats import date_format
from django.utils.translation import gettext_lazy as _
+from django.urls import reverse
from easy_thumbnails.alias import aliases
from easy_thumbnails.exceptions import InvalidImageFormatError
from easy_thumbnails.files import get_thumbnailer
@@ -397,6 +398,10 @@ class Meta:
def __str__(self):
return self.label
+ @classmethod
+ def get_add_url(cls):
+ return reverse('tourism:organizer_add')
+
class TouristicEvent(ZoningPropertiesMixin, AddPropertyMixin, PublishableMixin, GeotrekMapEntityMixin,
StructureRelated, PicturesMixin, TimeStampedModelMixin, NoDeleteMixin):
diff --git a/geotrek/tourism/templates/tourism/touristiceventorganizer_form.html b/geotrek/tourism/templates/tourism/touristiceventorganizer_form.html
new file mode 100644
index 0000000000..7ce60b145f
--- /dev/null
+++ b/geotrek/tourism/templates/tourism/touristiceventorganizer_form.html
@@ -0,0 +1,11 @@
+{% extends "mapentity/base_site.html" %}
+{% load static i18n crispy_forms_tags %}
+
+{% block title %}{% trans "Add Organizer" %}{% endblock title %}
+
+{% block navbar %}{% endblock navbar %}
+
+{% block content %}
+
{% trans "Add Organizer"%}
+{% crispy form %}
+{% endblock content %}
diff --git a/geotrek/tourism/urls.py b/geotrek/tourism/urls.py
index 71400c9408..a47f71849a 100644
--- a/geotrek/tourism/urls.py
+++ b/geotrek/tourism/urls.py
@@ -22,6 +22,8 @@
path('api//touristiccategories.json', tourism_views.TouristicCategoryView.as_view(), name="touristic_categories_json"),
path('api//touristiccontents//meta.html', tourism_views.TouristicContentMeta.as_view(), name="touristiccontent_meta"),
path('api//touristicevents//meta.html', tourism_views.TouristicEventMeta.as_view(), name="touristicevent_meta"),
+ path('popup/add/organizer/', tourism_views.TouristicEventOrganizerCreatePopup.as_view(), name='organizer_add'),
+
]
diff --git a/geotrek/tourism/views.py b/geotrek/tourism/views.py
index 9119e031df..f9fb011292 100644
--- a/geotrek/tourism/views.py
+++ b/geotrek/tourism/views.py
@@ -2,12 +2,16 @@
import os
from django.conf import settings
+from django.contrib.auth.decorators import login_required
from django.contrib.gis.db.models.functions import Transform
+from django.core.exceptions import PermissionDenied
from django.db.models import Q, Sum
-from django.http import Http404
+from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404
+from django.utils.decorators import method_decorator
from django.utils.translation import gettext as _
-from django.views.generic import DetailView
+from django.utils.html import escape
+from django.views.generic import DetailView, CreateView
from django_filters.rest_framework import DjangoFilterBackend
from mapentity.views import (MapEntityCreate, MapEntityUpdate, MapEntityList, MapEntityDetail,
MapEntityDelete, MapEntityFormat, MapEntityDocument)
@@ -25,8 +29,8 @@
from geotrek.common.viewsets import GeotrekMapentityViewSet
from geotrek.trekking.models import Trek
from .filters import TouristicContentFilterSet, TouristicEventFilterSet, TouristicEventApiFilterSet
-from .forms import TouristicContentForm, TouristicEventForm
-from .models import (TouristicContent, TouristicEvent, TouristicContentCategory, InformationDesk)
+from .forms import TouristicContentForm, TouristicEventForm, TouristicEventOrganizerFormPopup
+from .models import (TouristicContent, TouristicEvent, TouristicContentCategory, TouristicEventOrganizer, InformationDesk)
from .serializers import (TouristicContentSerializer, TouristicEventSerializer,
TouristicContentAPIGeojsonSerializer, TouristicEventAPIGeojsonSerializer,
InformationDeskGeojsonSerializer, TouristicContentAPISerializer, TouristicEventAPISerializer,
@@ -275,6 +279,23 @@ def get_context_data(self, **kwargs):
return context
+class TouristicEventOrganizerCreatePopup(CreateView):
+ model = TouristicEventOrganizer
+ form_class = TouristicEventOrganizerFormPopup
+
+ @method_decorator(login_required)
+ def dispatch(self, request, *args, **kwargs):
+ if not request.user.has_perm("tourism.add_touristiceventorganizer"):
+ raise PermissionDenied
+ return super().dispatch(request, *args, **kwargs)
+
+ def form_valid(self, form):
+ self.object = form.save()
+ return HttpResponse("""
+
+ """ % (escape(form.instance._get_pk_val()), escape(form.instance)))
+
+
class TouristicEventDocumentPublic(TouristicEventDocumentPublicMixin, DocumentPublic):
pass