Séparation des vues modération
This commit is contained in:
parent
76610993ba
commit
69ced85e1e
@ -26,7 +26,11 @@ from .views import (
|
|||||||
mentions_legales,
|
mentions_legales,
|
||||||
moderation_rules,
|
moderation_rules,
|
||||||
thank_you,
|
thank_you,
|
||||||
# tags
|
# Moderation
|
||||||
|
EventModerateView,
|
||||||
|
moderate_event_next,
|
||||||
|
moderate_from_date,
|
||||||
|
# Tags
|
||||||
view_tag,
|
view_tag,
|
||||||
view_tag_past,
|
view_tag_past,
|
||||||
TagUpdateView,
|
TagUpdateView,
|
||||||
@ -72,8 +76,6 @@ from .views import (
|
|||||||
run_all_rimports,
|
run_all_rimports,
|
||||||
EventDetailView,
|
EventDetailView,
|
||||||
EventUpdateView,
|
EventUpdateView,
|
||||||
EventModerateView,
|
|
||||||
moderate_event_next,
|
|
||||||
RecurrentImportCreateView,
|
RecurrentImportCreateView,
|
||||||
RecurrentImportDeleteView,
|
RecurrentImportDeleteView,
|
||||||
RecurrentImportUpdateView,
|
RecurrentImportUpdateView,
|
||||||
@ -92,7 +94,6 @@ from .views import (
|
|||||||
delete_cm_spam,
|
delete_cm_spam,
|
||||||
PlaceCreateView,
|
PlaceCreateView,
|
||||||
PlaceFromEventCreateView,
|
PlaceFromEventCreateView,
|
||||||
moderate_from_date,
|
|
||||||
update_from_source,
|
update_from_source,
|
||||||
change_status_event,
|
change_status_event,
|
||||||
EventDeleteView,
|
EventDeleteView,
|
||||||
@ -149,6 +150,38 @@ urlpatterns = [
|
|||||||
path("mentions-legales", mentions_legales, name="mentions_legales"),
|
path("mentions-legales", mentions_legales, name="mentions_legales"),
|
||||||
path("regles-de-moderation", moderation_rules, name="moderation_rules"),
|
path("regles-de-moderation", moderation_rules, name="moderation_rules"),
|
||||||
path("merci", thank_you, name="thank_you"),
|
path("merci", thank_you, name="thank_you"),
|
||||||
|
# Moderation
|
||||||
|
path("moderate", EventModerateView.as_view(), name="moderate"),
|
||||||
|
path(
|
||||||
|
"event/<int:pk>/moderate",
|
||||||
|
EventModerateView.as_view(),
|
||||||
|
name="moderate_event",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"event/<int:pk>/moderate-force",
|
||||||
|
EventModerateView.as_view(),
|
||||||
|
name="moderate_event_force",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"event/<int:pk>/moderate/after/<int:pred>",
|
||||||
|
EventModerateView.as_view(),
|
||||||
|
name="moderate_event_step",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"event/<int:pk>/moderate/back/<int:pred>",
|
||||||
|
EventModerateView.as_view(),
|
||||||
|
name="moderate_event_backstep",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"event/<int:pk>/moderate-next",
|
||||||
|
moderate_event_next,
|
||||||
|
name="moderate_event_next",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"moderate/<int:y>/<int:m>/<int:d>",
|
||||||
|
moderate_from_date,
|
||||||
|
name="moderate_from_date",
|
||||||
|
),
|
||||||
# TODO pas encore trié
|
# TODO pas encore trié
|
||||||
path("", home, name="home"),
|
path("", home, name="home"),
|
||||||
path("cat:<cat>/", home, name="home_category"),
|
path("cat:<cat>/", home, name="home_category"),
|
||||||
@ -218,37 +251,6 @@ urlpatterns = [
|
|||||||
path(
|
path(
|
||||||
"event/<int:pk>/edit-force", EventUpdateView.as_view(), name="edit_event_force"
|
"event/<int:pk>/edit-force", EventUpdateView.as_view(), name="edit_event_force"
|
||||||
),
|
),
|
||||||
path(
|
|
||||||
"event/<int:pk>/moderate",
|
|
||||||
EventModerateView.as_view(),
|
|
||||||
name="moderate_event",
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
"event/<int:pk>/moderate-force",
|
|
||||||
EventModerateView.as_view(),
|
|
||||||
name="moderate_event_force",
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
"event/<int:pk>/moderate/after/<int:pred>",
|
|
||||||
EventModerateView.as_view(),
|
|
||||||
name="moderate_event_step",
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
"event/<int:pk>/moderate/back/<int:pred>",
|
|
||||||
EventModerateView.as_view(),
|
|
||||||
name="moderate_event_backstep",
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
"event/<int:pk>/moderate-next",
|
|
||||||
moderate_event_next,
|
|
||||||
name="moderate_event_next",
|
|
||||||
),
|
|
||||||
path("moderate", EventModerateView.as_view(), name="moderate"),
|
|
||||||
path(
|
|
||||||
"moderate/<int:y>/<int:m>/<int:d>",
|
|
||||||
moderate_from_date,
|
|
||||||
name="moderate_from_date",
|
|
||||||
),
|
|
||||||
path(
|
path(
|
||||||
"event/<int:pk>/simple-clone/edit",
|
"event/<int:pk>/simple-clone/edit",
|
||||||
EventUpdateView.as_view(),
|
EventUpdateView.as_view(),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from .oldviews import *
|
from .oldviews import *
|
||||||
from .errors import *
|
from .errors import *
|
||||||
from .general_pages_views import *
|
from .general_pages_views import *
|
||||||
|
from .moderation_views import *
|
||||||
from .tag_views import *
|
from .tag_views import *
|
||||||
|
168
src/agenda_culturel/views/moderation_views.py
Normal file
168
src/agenda_culturel/views/moderation_views.py
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
from datetime import date
|
||||||
|
|
||||||
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
|
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
|
||||||
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
|
from django.http import Http404, HttpResponseRedirect
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views.generic import UpdateView
|
||||||
|
from django.db.models import Q, F
|
||||||
|
from django.utils.timezone import datetime
|
||||||
|
from ..forms import EventModerateForm
|
||||||
|
from ..models import Event
|
||||||
|
|
||||||
|
|
||||||
|
class EventModerateView(
|
||||||
|
SuccessMessageMixin,
|
||||||
|
PermissionRequiredMixin,
|
||||||
|
LoginRequiredMixin,
|
||||||
|
UpdateView,
|
||||||
|
):
|
||||||
|
model = Event
|
||||||
|
permission_required = "agenda_culturel.change_event"
|
||||||
|
template_name = "agenda_culturel/event_form_moderate.html"
|
||||||
|
form_class = EventModerateForm
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
kwargs["is_moderation_expert"] = (
|
||||||
|
self.request.user.userprofile.is_moderation_expert
|
||||||
|
)
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_success_message(self, cleaned_data):
|
||||||
|
txt = (
|
||||||
|
_(" A message has been sent to the person who proposed the event.")
|
||||||
|
if hasattr(self, "with_msg") and self.with_msg
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
return mark_safe(
|
||||||
|
_('The event <a href="{}">{}</a> has been moderated with success.').format(
|
||||||
|
self.object.get_absolute_url(), self.object.title
|
||||||
|
)
|
||||||
|
+ txt
|
||||||
|
)
|
||||||
|
|
||||||
|
def is_moderate_next(self):
|
||||||
|
return "after" in self.request.path.split("/")
|
||||||
|
|
||||||
|
def is_moderate_back(self):
|
||||||
|
return "back" in self.request.path.split("/")
|
||||||
|
|
||||||
|
def is_moderate_force(self):
|
||||||
|
return "moderate-force" in self.request.path.split("/")
|
||||||
|
|
||||||
|
def is_starting_moderation(self):
|
||||||
|
return "pk" not in self.kwargs
|
||||||
|
|
||||||
|
def is_moderation_from_date(self):
|
||||||
|
return "m" in self.kwargs and "y" in self.kwargs and "d" in self.kwargs
|
||||||
|
|
||||||
|
def get_next_event(start_day, start_time, opk):
|
||||||
|
# select non moderated events
|
||||||
|
qs = Event.objects.filter(moderated_date__isnull=True)
|
||||||
|
|
||||||
|
# select events after the current one
|
||||||
|
if start_time:
|
||||||
|
qs = qs.filter(
|
||||||
|
Q(start_day__gt=start_day)
|
||||||
|
| (
|
||||||
|
Q(start_day=start_day)
|
||||||
|
& (Q(start_time__isnull=True) | Q(start_time__gt=start_time))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
qs = qs.filter(Q(start_day__gte=start_day) & ~Q(pk=opk))
|
||||||
|
|
||||||
|
# get only possibly representative events
|
||||||
|
qs = qs.filter(
|
||||||
|
Q(other_versions__isnull=True)
|
||||||
|
| Q(other_versions__representative=F("pk"))
|
||||||
|
| Q(other_versions__representative__isnull=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
# remove trash events
|
||||||
|
qs = qs.filter(~Q(status=Event.STATUS.TRASH))
|
||||||
|
|
||||||
|
# sort by datetime
|
||||||
|
qs = qs.order_by("start_day", "start_time")
|
||||||
|
|
||||||
|
return qs.first()
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
if self.is_moderate_next():
|
||||||
|
context["pred"] = self.kwargs["pred"]
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
if self.is_starting_moderation():
|
||||||
|
now = datetime.now()
|
||||||
|
event = EventModerateView.get_next_event(now.date(), now.time(), None)
|
||||||
|
else:
|
||||||
|
event = super().get_object(queryset)
|
||||||
|
if event.status == Event.STATUS.DRAFT:
|
||||||
|
event.status = Event.STATUS.PUBLISHED
|
||||||
|
if self.is_moderate_back():
|
||||||
|
pred = Event.objects.filter(pk=self.kwargs["pred"]).first()
|
||||||
|
pred.free_modification_lock(self.request.user)
|
||||||
|
if self.is_moderate_force():
|
||||||
|
event.free_modification_lock(self.request.user, False)
|
||||||
|
return event
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
return super().post(request, args, kwargs)
|
||||||
|
except Http404:
|
||||||
|
return HttpResponseRedirect(
|
||||||
|
reverse_lazy("error_next_event", args=[self.object.pk])
|
||||||
|
)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
form.instance.set_no_modification_date_changed()
|
||||||
|
form.instance.set_in_moderation_process()
|
||||||
|
form.instance.set_processing_user(self.request.user)
|
||||||
|
self.with_msg = form.instance.notify_if_required(self.request)
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
if "save_and_next" in self.request.POST:
|
||||||
|
return reverse_lazy("moderate_event_next", args=[self.object.pk])
|
||||||
|
elif "save_and_edit_local" in self.request.POST:
|
||||||
|
return reverse_lazy("edit_event", args=[self.object.get_local_version().pk])
|
||||||
|
else:
|
||||||
|
return self.object.get_absolute_url()
|
||||||
|
|
||||||
|
|
||||||
|
@login_required(login_url="/accounts/login/")
|
||||||
|
@permission_required("agenda_culturel.change_event")
|
||||||
|
def moderate_event_next(request, pk):
|
||||||
|
# current event
|
||||||
|
obj = Event.objects.filter(pk=pk).first()
|
||||||
|
# free lock
|
||||||
|
obj.free_modification_lock(request.user)
|
||||||
|
start_day = obj.start_day
|
||||||
|
start_time = obj.start_time
|
||||||
|
|
||||||
|
next_obj = EventModerateView.get_next_event(start_day, start_time, pk)
|
||||||
|
if next_obj is None:
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"agenda_culturel/event_next_error_message.html",
|
||||||
|
{"pk": pk, "object": obj},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return HttpResponseRedirect(
|
||||||
|
reverse_lazy("moderate_event_step", args=[next_obj.pk, obj.pk])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required(login_url="/accounts/login/")
|
||||||
|
@permission_required("agenda_culturel.change_event")
|
||||||
|
def moderate_from_date(request, y, m, d):
|
||||||
|
d = date(y, m, d)
|
||||||
|
obj = EventModerateView.get_next_event(d, None, None)
|
||||||
|
return HttpResponseRedirect(reverse_lazy("moderate_event", args=[obj.pk]))
|
@ -14,10 +14,13 @@ from django.contrib.auth.mixins import (
|
|||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
||||||
|
from django.db.models import Aggregate, FloatField
|
||||||
|
from django.db.models import Avg, Max, Min
|
||||||
from django.db.models import Count, F, Func, OuterRef, Q, Subquery
|
from django.db.models import Count, F, Func, OuterRef, Q, Subquery
|
||||||
|
from django.db.models.aggregates import StdDev
|
||||||
|
from django.db.models.functions import ExtractDay
|
||||||
from django.db.models.functions import TruncMonth
|
from django.db.models.functions import TruncMonth
|
||||||
from django.http import (
|
from django.http import (
|
||||||
Http404,
|
|
||||||
HttpResponse,
|
HttpResponse,
|
||||||
HttpResponseForbidden,
|
HttpResponseForbidden,
|
||||||
HttpResponseRedirect,
|
HttpResponseRedirect,
|
||||||
@ -37,10 +40,6 @@ from django.views.generic.edit import (
|
|||||||
UpdateView,
|
UpdateView,
|
||||||
)
|
)
|
||||||
from honeypot.decorators import check_honeypot
|
from honeypot.decorators import check_honeypot
|
||||||
from django.db.models.aggregates import StdDev
|
|
||||||
from django.db.models import Avg, Max, Min
|
|
||||||
from django.db.models import Aggregate, FloatField
|
|
||||||
from django.db.models.functions import ExtractDay
|
|
||||||
|
|
||||||
from ..calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek
|
from ..calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek
|
||||||
from ..celery import app as celery_app
|
from ..celery import app as celery_app
|
||||||
@ -70,7 +69,6 @@ from ..forms import (
|
|||||||
EventAddPlaceForm,
|
EventAddPlaceForm,
|
||||||
EventForm,
|
EventForm,
|
||||||
EventFormWithContact,
|
EventFormWithContact,
|
||||||
EventModerateForm,
|
|
||||||
FixDuplicates,
|
FixDuplicates,
|
||||||
MergeDuplicates,
|
MergeDuplicates,
|
||||||
MessageEventForm,
|
MessageEventForm,
|
||||||
@ -159,6 +157,17 @@ class PaginatorFilter(Paginator):
|
|||||||
return page
|
return page
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Useful for translation
|
||||||
|
to_be_translated = [
|
||||||
|
_("Recurrent import name"),
|
||||||
|
_("Add another"),
|
||||||
|
_("Browse..."),
|
||||||
|
_("No file selected."),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def home(request, cat=None):
|
def home(request, cat=None):
|
||||||
return week_view(request, home=True, cat=cat)
|
return week_view(request, home=True, cat=cat)
|
||||||
|
|
||||||
@ -475,159 +484,6 @@ class EventUpdateView(
|
|||||||
return self.object.get_absolute_url()
|
return self.object.get_absolute_url()
|
||||||
|
|
||||||
|
|
||||||
class EventModerateView(
|
|
||||||
SuccessMessageMixin,
|
|
||||||
PermissionRequiredMixin,
|
|
||||||
LoginRequiredMixin,
|
|
||||||
UpdateView,
|
|
||||||
):
|
|
||||||
model = Event
|
|
||||||
permission_required = "agenda_culturel.change_event"
|
|
||||||
template_name = "agenda_culturel/event_form_moderate.html"
|
|
||||||
form_class = EventModerateForm
|
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
|
||||||
kwargs = super().get_form_kwargs()
|
|
||||||
kwargs["is_moderation_expert"] = (
|
|
||||||
self.request.user.userprofile.is_moderation_expert
|
|
||||||
)
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
def get_success_message(self, cleaned_data):
|
|
||||||
txt = (
|
|
||||||
_(" A message has been sent to the person who proposed the event.")
|
|
||||||
if hasattr(self, "with_msg") and self.with_msg
|
|
||||||
else ""
|
|
||||||
)
|
|
||||||
return mark_safe(
|
|
||||||
_('The event <a href="{}">{}</a> has been moderated with success.').format(
|
|
||||||
self.object.get_absolute_url(), self.object.title
|
|
||||||
)
|
|
||||||
+ txt
|
|
||||||
)
|
|
||||||
|
|
||||||
def is_moderate_next(self):
|
|
||||||
return "after" in self.request.path.split("/")
|
|
||||||
|
|
||||||
def is_moderate_back(self):
|
|
||||||
return "back" in self.request.path.split("/")
|
|
||||||
|
|
||||||
def is_moderate_force(self):
|
|
||||||
return "moderate-force" in self.request.path.split("/")
|
|
||||||
|
|
||||||
def is_starting_moderation(self):
|
|
||||||
return "pk" not in self.kwargs
|
|
||||||
|
|
||||||
def is_moderation_from_date(self):
|
|
||||||
return "m" in self.kwargs and "y" in self.kwargs and "d" in self.kwargs
|
|
||||||
|
|
||||||
def get_next_event(start_day, start_time, opk):
|
|
||||||
# select non moderated events
|
|
||||||
qs = Event.objects.filter(moderated_date__isnull=True)
|
|
||||||
|
|
||||||
# select events after the current one
|
|
||||||
if start_time:
|
|
||||||
qs = qs.filter(
|
|
||||||
Q(start_day__gt=start_day)
|
|
||||||
| (
|
|
||||||
Q(start_day=start_day)
|
|
||||||
& (Q(start_time__isnull=True) | Q(start_time__gt=start_time))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
qs = qs.filter(Q(start_day__gte=start_day) & ~Q(pk=opk))
|
|
||||||
|
|
||||||
# get only possibly representative events
|
|
||||||
qs = qs.filter(
|
|
||||||
Q(other_versions__isnull=True)
|
|
||||||
| Q(other_versions__representative=F("pk"))
|
|
||||||
| Q(other_versions__representative__isnull=True)
|
|
||||||
)
|
|
||||||
|
|
||||||
# remove trash events
|
|
||||||
qs = qs.filter(~Q(status=Event.STATUS.TRASH))
|
|
||||||
|
|
||||||
# sort by datetime
|
|
||||||
qs = qs.order_by("start_day", "start_time")
|
|
||||||
|
|
||||||
return qs.first()
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
if self.is_moderate_next():
|
|
||||||
context["pred"] = self.kwargs["pred"]
|
|
||||||
return context
|
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
|
||||||
if self.is_starting_moderation():
|
|
||||||
now = datetime.now()
|
|
||||||
event = EventModerateView.get_next_event(now.date(), now.time(), None)
|
|
||||||
else:
|
|
||||||
event = super().get_object(queryset)
|
|
||||||
if event.status == Event.STATUS.DRAFT:
|
|
||||||
event.status = Event.STATUS.PUBLISHED
|
|
||||||
if self.is_moderate_back():
|
|
||||||
pred = Event.objects.filter(pk=self.kwargs["pred"]).first()
|
|
||||||
pred.free_modification_lock(self.request.user)
|
|
||||||
if self.is_moderate_force():
|
|
||||||
event.free_modification_lock(self.request.user, False)
|
|
||||||
return event
|
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
return super().post(request, args, kwargs)
|
|
||||||
except Http404:
|
|
||||||
return HttpResponseRedirect(
|
|
||||||
reverse_lazy("error_next_event", args=[self.object.pk])
|
|
||||||
)
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
form.instance.set_no_modification_date_changed()
|
|
||||||
form.instance.set_in_moderation_process()
|
|
||||||
form.instance.set_processing_user(self.request.user)
|
|
||||||
self.with_msg = form.instance.notify_if_required(self.request)
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
if "save_and_next" in self.request.POST:
|
|
||||||
return reverse_lazy("moderate_event_next", args=[self.object.pk])
|
|
||||||
elif "save_and_edit_local" in self.request.POST:
|
|
||||||
return reverse_lazy("edit_event", args=[self.object.get_local_version().pk])
|
|
||||||
else:
|
|
||||||
return self.object.get_absolute_url()
|
|
||||||
|
|
||||||
|
|
||||||
@login_required(login_url="/accounts/login/")
|
|
||||||
@permission_required("agenda_culturel.change_event")
|
|
||||||
def moderate_event_next(request, pk):
|
|
||||||
# current event
|
|
||||||
obj = Event.objects.filter(pk=pk).first()
|
|
||||||
# free lock
|
|
||||||
obj.free_modification_lock(request.user)
|
|
||||||
start_day = obj.start_day
|
|
||||||
start_time = obj.start_time
|
|
||||||
|
|
||||||
next_obj = EventModerateView.get_next_event(start_day, start_time, pk)
|
|
||||||
if next_obj is None:
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"agenda_culturel/event_next_error_message.html",
|
|
||||||
{"pk": pk, "object": obj},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return HttpResponseRedirect(
|
|
||||||
reverse_lazy("moderate_event_step", args=[next_obj.pk, obj.pk])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required(login_url="/accounts/login/")
|
|
||||||
@permission_required("agenda_culturel.change_event")
|
|
||||||
def moderate_from_date(request, y, m, d):
|
|
||||||
d = date(y, m, d)
|
|
||||||
obj = EventModerateView.get_next_event(d, None, None)
|
|
||||||
return HttpResponseRedirect(reverse_lazy("moderate_event", args=[obj.pk]))
|
|
||||||
|
|
||||||
|
|
||||||
class EventDeleteView(
|
class EventDeleteView(
|
||||||
SuccessMessageMixin,
|
SuccessMessageMixin,
|
||||||
PermissionRequiredMixin,
|
PermissionRequiredMixin,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user