parent
ed3c58c313
commit
6f3000c51b
@ -250,3 +250,23 @@ class ModerationAnswerForm(ModelForm):
|
||||
'adds_tags': DynamicArrayWidgetTags(),
|
||||
'removes_tags': DynamicArrayWidgetTags()
|
||||
}
|
||||
|
||||
|
||||
class ModerateForm(ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Event
|
||||
fields = []
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
mqs = ModerationQuestion.objects.all()
|
||||
mas = ModerationAnswer.objects.all()
|
||||
|
||||
for q in mqs:
|
||||
self.fields[q.complete_id()] = ChoiceField(widget=RadioSelect, label=q.question, choices=[(a.pk, a.html_description()) for a in mas if a.question == q], required=True)
|
||||
for a in mas:
|
||||
if a.question == q and a.valid_event(self.instance):
|
||||
self.fields[q.complete_id()].initial = a.pk
|
||||
break
|
||||
|
18
src/agenda_culturel/migrations/0046_event_moderated_date.py
Normal file
18
src/agenda_culturel/migrations/0046_event_moderated_date.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.7 on 2024-04-13 09:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('agenda_culturel', '0045_auto_20240405_1941'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='moderated_date',
|
||||
field=models.DateTimeField(blank=True, null=True),
|
||||
),
|
||||
]
|
@ -1,6 +1,7 @@
|
||||
from django.db import models
|
||||
from django_better_admin_arrayfield.models.fields import ArrayField
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.template.defaultfilters import slugify
|
||||
from django.urls import reverse
|
||||
from colorfield.fields import ColorField
|
||||
@ -161,6 +162,7 @@ class Event(models.Model):
|
||||
created_date = models.DateTimeField(editable=False)
|
||||
imported_date = models.DateTimeField(blank=True, null=True)
|
||||
modified_date = models.DateTimeField(blank=True, null=True)
|
||||
moderated_date = models.DateTimeField(blank=True, null=True)
|
||||
|
||||
recurrence_dtstart = models.DateTimeField(editable=False, blank=True, null=True)
|
||||
recurrence_dtend = models.DateTimeField(editable=False, blank=True, null=True)
|
||||
@ -880,6 +882,9 @@ class ModerationQuestion(models.Model):
|
||||
def get_absolute_url(self):
|
||||
return reverse("view_mquestion", kwargs={"pk": self.pk})
|
||||
|
||||
def complete_id(self):
|
||||
return "question_" + str(self.pk)
|
||||
|
||||
|
||||
class ModerationAnswer(models.Model):
|
||||
|
||||
@ -890,3 +895,41 @@ class ModerationAnswer(models.Model):
|
||||
adds_tags = ArrayField(models.CharField(max_length=64), verbose_name=_('Adds tags'), help_text=_("A list of tags that will be added if you choose this answer."), blank=True, null=True)
|
||||
removes_tags = ArrayField(models.CharField(max_length=64), verbose_name=_('Removes tags'), help_text=_("A list of tags that will be removed if you choose this answer."), blank=True, null=True)
|
||||
|
||||
|
||||
def complete_id(self):
|
||||
return "answer_" + str(self.question.pk) + '_' + str(self.pk)
|
||||
|
||||
def html_description(self):
|
||||
result = self.answer + '<br /><span class="helptext">'
|
||||
if self.adds_tags:
|
||||
result += ' '.join(['<span role="button" class="small-cat">' + a + '</span>' for a in self.adds_tags])
|
||||
if self.removes_tags:
|
||||
result += ' '.join(['<span role="button" class="small-cat strike">' + a + '</span>' for a in self.removes_tags])
|
||||
result += "</span>"
|
||||
return mark_safe(result)
|
||||
|
||||
def valid_event(self, event):
|
||||
if event.tags:
|
||||
for t in self.adds_tags:
|
||||
if t not in event.tags:
|
||||
return False
|
||||
|
||||
for t in self.removes_tags:
|
||||
if t in event.tags:
|
||||
return False
|
||||
|
||||
return True
|
||||
else:
|
||||
return not self.adds_tags or len(self.adds_tags) == 0
|
||||
|
||||
def apply_answer(self, event):
|
||||
if not self.adds_tags:
|
||||
self.adds_tags = []
|
||||
if not self.removes_tags:
|
||||
self.removes_tags = []
|
||||
|
||||
logger.info('on applique la réponse ' + self.answer)
|
||||
if event.tags:
|
||||
event.tags = list((set(event.tags) | set(self.adds_tags)) - set(self.removes_tags))
|
||||
else:
|
||||
event.tags = self.adds_tags
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
{% load utils_extra %}
|
||||
<a href="{% url 'edit_event' event.id %}" role="button">modifier {% picto_from_name "edit" %}</a>
|
||||
<a href="{% url 'moderate_event' event.id %}" role="button">modérer {% picto_from_name "edit" %}</a>
|
||||
<a href="{% url 'edit_event' event.id %}" role="button">modifier {% picto_from_name "edit-3" %}</a>
|
||||
|
||||
{% if event.status != "published" %}
|
||||
<a href="{% url 'change_status_event' event.id 'published' %}" role="button">publier {% picto_from_name "eye" %}</a>
|
||||
|
@ -0,0 +1,30 @@
|
||||
<footer class="remarque">
|
||||
Informations complémentaires non éditables :
|
||||
<ul>
|
||||
{% if object.created_date %}<li>Création : {{ object.created_date }}</li>{% endif %}
|
||||
{% if object.modified_date %}<li>Dernière modification : {{ object.modified_date }}</li>{% endif %}
|
||||
{% if object.moderated_date %}<li>Dernière modération : {{ object.moderated_date }}</li>{% endif %}
|
||||
{% if object.imported_date %}<li>Dernière importation : {{ object.imported_date }}</li>{% endif %}
|
||||
{% if object.uuids %}
|
||||
{% if object.uuids|length > 0 %}
|
||||
<li>UUIDs (identifiants uniques d'événements dans les sources) :
|
||||
<ul>
|
||||
{% for u in object.uuids %}
|
||||
<li>{{ u }}</li>
|
||||
{% endfor %}
|
||||
</ul></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if object.import_sources %}
|
||||
{% if object.import_sources|length > 0 %}
|
||||
<li>Sources d'import :
|
||||
<ul>
|
||||
{% for u in object.import_sources %}
|
||||
<li><a href="{{ u }}">{{ u }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</footer>
|
@ -46,35 +46,7 @@
|
||||
</div>
|
||||
</form>
|
||||
{% if object %}
|
||||
<footer class="remarque">
|
||||
Informations complémentaires non éditables :
|
||||
<ul>
|
||||
{% if object.created_date %}<li>Création : {{ object.created_date }}</li>{% endif %}
|
||||
{% if object.modified_date %}<li>Dernière modification : {{ object.modified_date }}</li>{% endif %}
|
||||
{% if object.imported_date %}<li>Dernière importation : {{ object.imported_date }}</li>{% endif %}
|
||||
{% if object.uuids %}
|
||||
{% if object.uuids|length > 0 %}
|
||||
<li>UUIDs (identifiants uniques d'événements dans les sources) :
|
||||
<ul>
|
||||
{% for u in object.uuids %}
|
||||
<li>{{ u }}</li>
|
||||
{% endfor %}
|
||||
</ul></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if object.import_sources %}
|
||||
{% if object.import_sources|length > 0 %}
|
||||
<li>Sources d'import :
|
||||
<ul>
|
||||
{% for u in object.import_sources %}
|
||||
<li><a href="{{ u }}">{{ u }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</footer>
|
||||
{% include "agenda_culturel/event-info-inc.html" %}
|
||||
{% endif %}
|
||||
</article>
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
{% extends "agenda_culturel/event_form.html" %}
|
||||
{% load static %}
|
||||
|
||||
|
||||
{% block title %}Modérer {{ object.title }}{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% load static_content_extra %}
|
||||
|
||||
<article>
|
||||
<header>
|
||||
<h1>Modération de l'événement {{ object.title }} ({{ object.start_day }})</h1>
|
||||
</header>
|
||||
|
||||
{% include "agenda_culturel/single-event/event-single-inc.html" with event=object noedit=1 %}
|
||||
|
||||
<div id="container"></div>
|
||||
<form method="post">{% csrf_token %}
|
||||
{{ form.media }}
|
||||
{{ form.as_p }}
|
||||
<div class="grid">
|
||||
<a href="{% if request.META.HTTP_REFERER %}{{ request.META.HTTP_REFERER }}{% else %}{{ object.get_absolute_url }}{% endif %}" role="button" class="secondary">Annuler</a>
|
||||
<input type="submit" value="Enregistrer">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% include "agenda_culturel/event-info-inc.html" %}
|
||||
|
||||
</article>
|
||||
|
||||
{% endblock %}
|
@ -65,9 +65,12 @@
|
||||
{% if event.modified %}
|
||||
— dernière modification : {{ event.modified_date }}
|
||||
{% endif %}
|
||||
{% if event.moderated_date %}
|
||||
— dernière modération : {{ event.moderated_date }}
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
{% if perms.agenda_culturel.change_event %}
|
||||
{% if perms.agenda_culturel.change_event and not noedit %}
|
||||
<div class="buttons">
|
||||
{% include "agenda_culturel/edit-buttons-inc.html" with event=event %}
|
||||
</div>
|
||||
|
@ -25,6 +25,7 @@ urlpatterns = [
|
||||
path("event/<int:pk>/change-status/<status>", change_status_event, name="change_status_event"),
|
||||
path("event/<int:pk>/delete", EventDeleteView.as_view(), name="delete_event"),
|
||||
path("event/<int:year>/<int:month>/<int:day>/<int:pk>/set_duplicate", set_duplicate, name="set_duplicate"),
|
||||
path("event/<int:pk>/moderate", EventModerateView.as_view(), name="moderate_event"),
|
||||
path("ajouter", import_from_url, name="add_event"),
|
||||
path("admin/", admin.site.urls),
|
||||
path('accounts/', include('django.contrib.auth.urls')),
|
||||
|
@ -11,7 +11,7 @@ from django.http import HttpResponseRedirect
|
||||
from django.urls import reverse
|
||||
import urllib
|
||||
|
||||
from .forms import EventSubmissionForm, EventForm, BatchImportationForm, FixDuplicates, SelectEventInList, MergeDuplicates, RecurrentImportForm, CategorisationRuleImportForm, ModerationQuestionForm, ModerationAnswerForm
|
||||
from .forms import EventSubmissionForm, EventForm, BatchImportationForm, FixDuplicates, SelectEventInList, MergeDuplicates, RecurrentImportForm, CategorisationRuleImportForm, ModerationQuestionForm, ModerationAnswerForm, ModerateForm
|
||||
|
||||
from .models import Event, Category, StaticContent, ContactMessage, BatchImportation, DuplicatedEvents, RecurrentImport, CategorisationRule, remove_accents, ModerationQuestion, ModerationAnswer
|
||||
from django.utils import timezone
|
||||
@ -259,6 +259,27 @@ class EventDetailView(UserPassesTestMixin, DetailView):
|
||||
return obj
|
||||
|
||||
|
||||
class EventModerateView(SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
|
||||
model = Event
|
||||
permission_required = ["agenda_culturel.changes_event", "use_moderation_question"]
|
||||
success_message = _('The event has been successfully modified.')
|
||||
form_class = ModerateForm
|
||||
template_name = 'agenda_culturel/event_moderation_form.html'
|
||||
|
||||
def form_valid(self, form):
|
||||
|
||||
mas = ModerationAnswer.objects.all()
|
||||
logger.warning("ON valide la forme")
|
||||
|
||||
for f in form.cleaned_data:
|
||||
ModerationAnswer.objects.get(pk=form.cleaned_data[f]).apply_answer(form.instance)
|
||||
|
||||
form.instance.moderated_date = timezone.now()
|
||||
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
|
||||
@login_required(login_url="/accounts/login/")
|
||||
@permission_required('agenda_culturel.change_event')
|
||||
def change_status_event(request, pk, status):
|
||||
|
Loading…
x
Reference in New Issue
Block a user