Ajout d'un booléen "portée locale"

Fix #360
This commit is contained in:
Jean-Marie Favreau 2025-03-13 23:09:09 +01:00
parent 55e8c1a323
commit a66559aac0
10 changed files with 383 additions and 270 deletions

View File

@ -1,5 +1,6 @@
from datetime import date, timedelta
from urllib.parse import parse_qs, urlencode, urlparse
import re
import django_filters
from django import forms
@ -46,6 +47,15 @@ class EventFilter(django_filters.FilterSet):
empty_label=None,
)
include_local_events = django_filters.ChoiceFilter(
label="Inclure les événements de portée locale",
choices=[(False, _("No")), (True, _("Yes"))],
method="no_filter",
widget=forms.Select,
null_label=None,
empty_label=None,
)
exclude_tags = django_filters.MultipleChoiceFilter(
label="Exclure les étiquettes",
choices=[],
@ -138,6 +148,10 @@ class EventFilter(django_filters.FilterSet):
@property
def qs(self):
parent = super().qs
if not self.with_local_events():
parent = parent.filter(local_event=False)
if (
self.get_cleaned_data("position") is None
or self.get_cleaned_data("radius") is None
@ -200,6 +214,9 @@ class EventFilter(django_filters.FilterSet):
def get_exclude_tags(self):
return self.get_cleaned_data("exclude_tags")
def with_local_events(self):
return self.get_cleaned_data("include_local_events") == "True"
def get_status(self):
return self.get_cleaned_data("status")
@ -261,6 +278,7 @@ class EventFilter(django_filters.FilterSet):
(self.get_cleaned_data("position") is not None)
and (self.get_cleaned_data("radius") is not None)
)
or self.with_local_events()
)
def is_active(self, only_categories=False):
@ -276,6 +294,7 @@ class EventFilter(django_filters.FilterSet):
(self.get_cleaned_data("position") is not None)
and (self.get_cleaned_data("radius") is not None)
)
or self.with_local_events()
)
def is_selected_tag(self, tag):
@ -333,6 +352,14 @@ class EventFilter(django_filters.FilterSet):
+ str(location.suggested_distance)
)
def get_url_add_local_events(self):
result = self.request.get_full_path()
return result + ("&" if "?" in result else "?") + "include_local_events=True"
def get_url_remove_local_events(self):
result = self.request.get_full_path()
return re.sub("[?&]include_local_events=True", "", result)
class EventFilterAdmin(django_filters.FilterSet):
status = django_filters.MultipleChoiceFilter(
@ -593,6 +620,7 @@ class SearchEventFilter(django_filters.FilterSet):
"category",
"tags",
"start_day",
"local_event",
]
def __init__(self, *args, **kwargs):

View File

@ -355,6 +355,7 @@ class EventForm(GroupFormMixin, ModelForm):
self.add_group("location", _("Location"))
self.fields["location"].group_id = "location"
self.fields["exact_location"].group_id = "location"
self.fields["local_event"].group_id = "location"
self.add_group("illustration", _("Illustration"))
self.fields["local_image"].group_id = "illustration"
@ -455,7 +456,14 @@ class EventModerateForm(ModelForm):
class Meta:
model = Event
fields = ["status", "category", "organisers", "exact_location", "tags"]
fields = [
"status",
"category",
"organisers",
"exact_location",
"local_event",
"tags",
]
widgets = {"status": RadioSelect}
def __init__(self, *args, **kwargs):

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
# Generated by Django 4.2.19 on 2025-03-13 22:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("agenda_culturel", "0152_alter_recurrentimport_recurrence"),
]
operations = [
migrations.AddField(
model_name="event",
name="local_event",
field=models.BooleanField(
default=False,
help_text="If the event is a local event, it will not be proposed by default in daily, weekly or monthly views, unless the user has explicitly indicated that he wishes to see these events.",
verbose_name="Local event",
),
),
]

View File

@ -768,6 +768,16 @@ class Event(models.Model):
blank=True,
)
local_event = models.BooleanField(
verbose_name=_("Local event"),
help_text=_(
"If the event is a local event, it will not be proposed by default in daily, weekly or monthly views, unless the user has explicitly indicated that he wishes to see these events."
),
default=False,
null=False,
blank=False,
)
description = models.TextField(
verbose_name=_("Description"),
blank=True,

View File

@ -17,6 +17,7 @@
{% for s in filter.get_status_names %}{{ s }}{% endfor %}
{{ filter.get_recurrence_filtering }}
{{ filter.get_position_radius }}
{% if filter.with_local_events %}avec les événements de portée locale{% endif %}
{% else %}
<strong>Filtrer</strong>
{% endif %}
@ -30,7 +31,7 @@
<div class="grid two-columns-equal">
<article>
{% for f in filter.form.visible_fields %}
{% if f.id_for_label and f.id_for_label in "id_position,id_radius" %}
{% if f.id_for_label and f.id_for_label in "id_position,id_radius,id_include_local_events" %}
<div>
{{ f.errors }}
{{ f.label_tag }} {{ f }}
@ -41,7 +42,7 @@
</article>
<article>
{% for f in filter.form.visible_fields %}
{% if not f.id_for_label or not f.id_for_label in "id_position,id_radius" %}
{% if not f.id_for_label or not f.id_for_label in "id_position,id_radius,id_include_local_events" %}
<p>
{{ f.errors }}
{{ f.label_tag }} {{ f }}

View File

@ -49,6 +49,11 @@
{% endif %}
</hgroup>
{% endif %}
{% if event.local_event %}
<p>
<em>Événement de portée locale</em>
</p>
{% endif %}
{% if event|need_complete_display:True %}
<p>
{% picto_from_name "calendar" %}

View File

@ -58,6 +58,11 @@
{% endif %}
{% endif %}
</p>
{% if event.local_event %}
<p class="subentry-search">
<em>Événement de portée locale</em>
</p>
{% endif %}
</header>
{% if event.has_recurrences %}
<p class="subentry-search">

View File

@ -106,6 +106,11 @@
{% endif %}
{% endif %}
{% endif %}
{% if event.local_event %}
<p>
<em>Événement de portée locale</em>
</p>
{% endif %}
{% with event.get_shown_organisers as organisers %}
{% if organisers and organisers|length > 0 %}
<p>

View File

@ -13,7 +13,22 @@ def show_suggested_positions(filter):
filter.form.full_clean()
if filter.is_filtered_by_position_radius():
return ""
if filter.with_local_events():
return mark_safe(
' <a class="small-location" role="button" href="'
+ filter.get_url_remove_local_events()
+ '">'
+ picto_from_name("minus-circle")
+ " cacher les événements de portée locale</a>"
)
else:
return mark_safe(
' <a class="small-location" role="button" href="'
+ filter.get_url_add_local_events()
+ '">'
+ picto_from_name("plus-circle")
+ " voir les événements de portée locale</a>"
)
locations = (
ReferenceLocation.objects.all()