Ajout d'une classe période remarquable
See #354
This commit is contained in:
parent
0581a46f98
commit
60b0255942
@ -20,6 +20,7 @@ from .models import (
|
||||
Tag,
|
||||
UserProfile,
|
||||
SiteConfiguration,
|
||||
SpecialPeriod,
|
||||
)
|
||||
|
||||
admin.site.register(SiteConfiguration, SingletonModelAdmin)
|
||||
@ -35,6 +36,7 @@ admin.site.register(Message)
|
||||
admin.site.register(ReferenceLocation)
|
||||
admin.site.register(Organisation)
|
||||
admin.site.register(UserProfile)
|
||||
admin.site.register(SpecialPeriod)
|
||||
|
||||
|
||||
class URLWidget(DynamicArrayWidget):
|
||||
|
@ -36,6 +36,7 @@ from .models import (
|
||||
RecurrentImport,
|
||||
Tag,
|
||||
UserProfile,
|
||||
SpecialPeriod,
|
||||
)
|
||||
from .templatetags.event_extra import event_field_verbose_name, field_to_html
|
||||
from .templatetags.utils_extra import int_to_abc
|
||||
@ -991,3 +992,14 @@ class UserProfileForm(ModelForm):
|
||||
class Meta:
|
||||
model = UserProfile
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class SpecialPeriodForm(ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = SpecialPeriod
|
||||
fields = "__all__"
|
||||
widgets = {
|
||||
"start_date": TextInput(attrs={"type": "date"}),
|
||||
"end_date": TextInput(attrs={"type": "date"}),
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
46
src/agenda_culturel/migrations/0165_specialperiod.py
Normal file
46
src/agenda_culturel/migrations/0165_specialperiod.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Generated by Django 4.2.19 on 2025-04-04 20:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("agenda_culturel", "0164_alter_recurrentimport_processor"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="SpecialPeriod",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=255, verbose_name="Period name")),
|
||||
("start_date", models.DateField(verbose_name="Start day")),
|
||||
("end_date", models.DateField(verbose_name="End day")),
|
||||
(
|
||||
"periodtype",
|
||||
models.CharField(
|
||||
choices=[
|
||||
("public holidays", "public holidays"),
|
||||
("school vacations", "school vacations"),
|
||||
],
|
||||
default="public holidays",
|
||||
max_length=20,
|
||||
verbose_name="Period type",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Special period",
|
||||
"verbose_name_plural": "Special periods",
|
||||
},
|
||||
),
|
||||
]
|
@ -3155,3 +3155,48 @@ class CategorisationRule(models.Model):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class SpecialPeriod(models.Model):
|
||||
|
||||
name = models.CharField(verbose_name=_("Period name"), max_length=255)
|
||||
start_date = models.DateField(verbose_name=_("Start day"))
|
||||
end_date = models.DateField(verbose_name=_("End day"))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Special period")
|
||||
verbose_name_plural = _("Special periods")
|
||||
|
||||
class PERIODTYPE(models.TextChoices):
|
||||
PUBLICHOLIDAYS = "public holidays", _("public holidays")
|
||||
SCHOOLVACATIONS = "school vacations", _("school vacations")
|
||||
|
||||
periodtype = models.CharField(
|
||||
_("Period type"),
|
||||
max_length=20,
|
||||
choices=PERIODTYPE.choices,
|
||||
default=PERIODTYPE.PUBLICHOLIDAYS,
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
# Call the parent class's clean() method
|
||||
super().clean()
|
||||
|
||||
# Check that the end date is after or equal to the start date
|
||||
if self.end_date < self.start_date:
|
||||
raise ValidationError(
|
||||
{
|
||||
"end_date": _(
|
||||
"The end date must be after or equal to the start date."
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
n = self.periodtype + ' "' + self.name + '" '
|
||||
if self.start_date == self.end_date:
|
||||
return n + _(" on ") + str(self.start_date)
|
||||
else:
|
||||
return (
|
||||
n + _(" from ") + str(self.start_date) + _(" to ") + str(self.end_day)
|
||||
)
|
||||
|
@ -101,6 +101,17 @@
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% if perms.agenda_culturel.edit_specialperiod %}
|
||||
<h3>Périodes remarquables</h3>
|
||||
<nav>
|
||||
<ul>
|
||||
<li>
|
||||
<a {% if current == "special_periods" %}class="selected"{% endif %}
|
||||
href="{% url 'list_specialperiods' %}">Périodes remarquables</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% if user.is_staff %}
|
||||
<h3>Configuration interne</h3>
|
||||
<nav>
|
||||
|
@ -0,0 +1,20 @@
|
||||
{% extends "agenda_culturel/page.html" %}
|
||||
{% block title %}
|
||||
{% block og_title %}Supprimer la période remarquable {{ object }}{% endblock %}
|
||||
{% endblock %}
|
||||
{% block fluid %}{% endblock %}
|
||||
{% block configurer-bouton %}{% endblock %}
|
||||
{% block content %}
|
||||
<h1>Suppression de la période remarquable {{ object.pk }}</h1>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<p>Êtes-vous sûr·e de vouloir supprimer la période remarquable « {{ object }} ({{ object.pk }}) » ?</p>
|
||||
{{ form }}
|
||||
<div class="grid buttons">
|
||||
<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="Confirmer">
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
@ -0,0 +1,31 @@
|
||||
{% extends "agenda_culturel/page.html" %}
|
||||
{% block title %}
|
||||
{% block og_title %}
|
||||
{% if object %}
|
||||
Modifier la période remarquable #{{ object.pk }}
|
||||
{% else %}
|
||||
Ajouter une période remarquable
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
{% block fluid %}{% endblock %}
|
||||
{% block content %}
|
||||
<h1>
|
||||
{% if object %}
|
||||
Modifier la période remarquable #{{ object.pk }}
|
||||
{% else %}
|
||||
Ajouter une période remarquable
|
||||
{% endif %}
|
||||
</h1>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<div class="grid buttons">
|
||||
<a href="{% if request.META.HTTP_REFERER %}{{ request.META.HTTP_REFERER }}{% else %}{% url 'list_specialperiods' %}{% endif %}"
|
||||
role="button"
|
||||
class="secondary">Annuler</a>
|
||||
<input type="submit" value="Enregistrer">
|
||||
</div>
|
||||
</form>
|
||||
{{ form.media }}
|
||||
{% endblock %}
|
@ -0,0 +1,56 @@
|
||||
{% extends "agenda_culturel/page.html" %}
|
||||
{% block title %}
|
||||
{% block og_title %}Administration des périodes remarquables{% endblock %}
|
||||
{% endblock %}
|
||||
{% load utils_extra %}
|
||||
{% load cat_extra %}
|
||||
{% block entete_header %}
|
||||
{% css_categories %}
|
||||
{% endblock %}
|
||||
{% block sidemenu-bouton %}
|
||||
<li>
|
||||
<a href="#contenu-principal" aria-label="Aller au contenu">{% picto_from_name "chevron-up" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#sidebar" aria-label="Aller au menu latéral">{% picto_from_name "chevron-down" %}</a>
|
||||
</li>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="grid two-columns">
|
||||
<article>
|
||||
<header>
|
||||
<div class="slide-buttons">
|
||||
<a href="{% url 'add_specialperiod' %}" role="button">Ajouter {% picto_from_name "plus-circle" %}</a>
|
||||
</div>
|
||||
<h1>Périodes spéciales</h1>
|
||||
</header>
|
||||
{% include "agenda_culturel/navigation.html" with page_obj=page_obj %}
|
||||
{% if object_list %}
|
||||
{% for sp in object_list %}
|
||||
<article>
|
||||
<header>
|
||||
<div class="slide-buttons">
|
||||
<a href="{% url 'edit_specialperiod' sp.pk %}" role="button">Modifier {% picto_from_name "edit-3" %}</a>
|
||||
<a href="{% url 'delete_specialperiod' sp.pk %}" role="button">Supprimer {% picto_from_name "trash-2" %}</a>
|
||||
</div>
|
||||
<h2>{{ sp.get_periodtype_display }} : {{ sp.name }}</h2>
|
||||
<p>
|
||||
{% if sp.start_date == sp.end_date %}
|
||||
le {{ sp.start_date }}
|
||||
{% else %}
|
||||
du {{ sp.start_date }} au {{ sp.end_date }}
|
||||
{% endif %}
|
||||
</p>
|
||||
</header>
|
||||
</article>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>Il n'y a aucune période spéciale définie.</p>
|
||||
{% endif %}
|
||||
<footer>
|
||||
{% include "agenda_culturel/navigation.html" with page_obj=page_obj %}
|
||||
</footer>
|
||||
</article>
|
||||
{% include "agenda_culturel/side-nav.html" with current="special_periods" %}
|
||||
</div>
|
||||
{% endblock %}
|
@ -106,6 +106,10 @@ from .views import (
|
||||
moderation_rules,
|
||||
import_requirements,
|
||||
UserProfileUpdateView,
|
||||
SpecialPeriodCreateView,
|
||||
SpecialPeriodDeleteView,
|
||||
SpecialPeriodListView,
|
||||
SpecialPeriodUpdateView,
|
||||
)
|
||||
|
||||
event_dict = {
|
||||
@ -480,6 +484,24 @@ urlpatterns = [
|
||||
),
|
||||
path("cache/clear", clear_cache, name="clear_cache"),
|
||||
path("profile/edit", UserProfileUpdateView.as_view(), name="edit_profile"),
|
||||
path(
|
||||
"specialperiods/", SpecialPeriodListView.as_view(), name="list_specialperiods"
|
||||
),
|
||||
path(
|
||||
"specialperiods/add",
|
||||
SpecialPeriodCreateView.as_view(),
|
||||
name="add_specialperiod",
|
||||
),
|
||||
path(
|
||||
"specialperiods/<pk>/edit",
|
||||
SpecialPeriodUpdateView.as_view(),
|
||||
name="edit_specialperiod",
|
||||
),
|
||||
path(
|
||||
"specialperiods/<pk>/delete",
|
||||
SpecialPeriodDeleteView.as_view(),
|
||||
name="delete_specialperiod",
|
||||
),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
|
@ -85,6 +85,7 @@ from .forms import (
|
||||
URLSubmissionFormSet,
|
||||
URLSubmissionFormWithContact,
|
||||
UserProfileForm,
|
||||
SpecialPeriodForm,
|
||||
)
|
||||
from .import_tasks.extractor import Extractor
|
||||
from .models import (
|
||||
@ -102,6 +103,7 @@ from .models import (
|
||||
remove_accents,
|
||||
UserProfile,
|
||||
SiteConfiguration,
|
||||
SpecialPeriod,
|
||||
)
|
||||
from .utils import PlaceGuesser
|
||||
|
||||
@ -3103,6 +3105,11 @@ def clear_cache(request):
|
||||
)
|
||||
|
||||
|
||||
#########################
|
||||
## User profile
|
||||
#########################
|
||||
|
||||
|
||||
class UserProfileUpdateView(
|
||||
SuccessMessageMixin,
|
||||
LoginRequiredMixin,
|
||||
@ -3115,3 +3122,50 @@ class UserProfileUpdateView(
|
||||
|
||||
def get_object(self):
|
||||
return self.request.user.userprofile
|
||||
|
||||
|
||||
#########################
|
||||
## Special period
|
||||
#########################
|
||||
|
||||
|
||||
class SpecialPeriodCreateView(
|
||||
PermissionRequiredMixin, LoginRequiredMixin, SuccessMessageMixin, CreateView
|
||||
):
|
||||
model = SpecialPeriod
|
||||
permission_required = "agenda_culturel.add_specialperiod"
|
||||
success_message = _("The special period has been successfully created.")
|
||||
success_url = reverse_lazy("list_specialperiods")
|
||||
form_class = SpecialPeriodForm
|
||||
|
||||
|
||||
class SpecialPeriodListView(PermissionRequiredMixin, LoginRequiredMixin, ListView):
|
||||
model = SpecialPeriod
|
||||
paginate_by = 10
|
||||
permission_required = "agenda_culturel.add_specialperiod"
|
||||
ordering = ["start_date", "name__unaccent"]
|
||||
|
||||
|
||||
class SpecialPeriodDeleteView(
|
||||
SuccessMessageMixin,
|
||||
PermissionRequiredMixin,
|
||||
LoginRequiredMixin,
|
||||
DeleteView,
|
||||
):
|
||||
model = SpecialPeriod
|
||||
permission_required = "agenda_culturel.delete_specialperiod"
|
||||
success_url = reverse_lazy("list_specialperiods")
|
||||
success_message = _("The special period has been successfully deleted.")
|
||||
|
||||
|
||||
class SpecialPeriodUpdateView(
|
||||
SuccessMessageMixin,
|
||||
PermissionRequiredMixin,
|
||||
LoginRequiredMixin,
|
||||
UpdateView,
|
||||
):
|
||||
model = SpecialPeriod
|
||||
permission_required = "agenda_culturel.change_specialperiod"
|
||||
success_message = _("The special period has been successfully updated.")
|
||||
success_url = reverse_lazy("list_specialperiods")
|
||||
form_class = SpecialPeriodForm
|
||||
|
Loading…
x
Reference in New Issue
Block a user