improve event organizer selection, show on web

This commit is contained in:
2024-06-10 03:06:26 +02:00
parent 2f3b359d9d
commit f7debf565d
17 changed files with 292 additions and 16 deletions

View File

@ -1,2 +1,13 @@
from wagtail.admin.viewsets.chooser import ChooserViewSet
# Create your views here.
class AssociationChooserViewSet(ChooserViewSet):
model = "associations.AssociationPage"
icon = "group"
choose_one_text = "Choose an association"
choose_another_text = "Choose another association"
edit_item_text = "Edit this association"
# form_fields = ["name"]
association_chooser_viewset = AssociationChooserViewSet("association_chooser")

View File

@ -0,0 +1,8 @@
from wagtail import hooks
from .views import association_chooser_viewset
@hooks.register("register_admin_viewset")
def register_viewset():
return association_chooser_viewset

View File

@ -0,0 +1,3 @@
from .views import association_chooser_viewset
AssociationChooserWidget = association_chooser_viewset.widget_class

View File

@ -0,0 +1,25 @@
# Generated by Django 5.0.6 on 2024-06-08 23:06
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('associations', '0010_alter_associationindex_body_and_more'),
('events', '0030_eventcategory_pig_alter_eventpage_pig'),
]
operations = [
migrations.AddField(
model_name='eventorganizer',
name='external_url',
field=models.URLField(blank=True, help_text='Lenke til nettstedet til ekstern arrangør', max_length=512),
),
migrations.AlterField(
model_name='eventorganizer',
name='association',
field=models.ForeignKey(blank=True, help_text='Om en samfundsforening eller et utvalg står bak, velg det her.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='organizers', to='associations.associationpage'),
),
]

View File

@ -0,0 +1,32 @@
# Generated by Django 5.0.6 on 2024-06-09 00:27
import django.db.models.deletion
import modelcluster.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0031_eventorganizer_external_url_and_more'),
]
operations = [
migrations.RemoveField(
model_name='eventpage',
name='organizers',
),
migrations.CreateModel(
name='EventOrganizerLink',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
('event', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='organizers', to='events.eventpage')),
('organizer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='organized_events', to='events.eventorganizer')),
],
options={
'verbose_name': 'Arrangør',
'verbose_name_plural': 'Arrangører',
},
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 5.0.6 on 2024-06-09 00:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0032_remove_eventpage_organizers_eventorganizerlink'),
]
operations = [
migrations.AddConstraint(
model_name='eventorganizerlink',
constraint=models.UniqueConstraint(models.F('event'), models.F('organizer'), name='event_organizer_link_event_organizer_unique'),
),
]

View File

@ -0,0 +1,25 @@
# Generated by Django 5.0.6 on 2024-06-10 00:55
import django.db.models.deletion
import modelcluster.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0033_eventorganizerlink_event_organizer_link_event_organizer_unique'),
]
operations = [
migrations.AddField(
model_name='eventpage',
name='organizers',
field=models.ManyToManyField(through='events.EventOrganizerLink', to='events.eventorganizer'),
),
migrations.AlterField(
model_name='eventorganizerlink',
name='event',
field=modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='organizer_links', to='events.eventpage'),
),
]

View File

@ -1,6 +1,6 @@
from django import forms
from django.db import models
from django.db.models import Min, Q
from django.db.models import Min, Q, UniqueConstraint
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from grapple.helpers import register_query_field, register_singular_query_field
@ -21,12 +21,13 @@ from wagtail.admin.panels import (
HelpPanel,
InlinePanel,
MultiFieldPanel,
PageChooserPanel,
MultipleChooserPanel,
TitleFieldPanel,
)
from wagtail.models import Orderable, Page, PageManager, PageQuerySet
from wagtail.snippets.models import register_snippet
from associations.widgets import AssociationChooserWidget
from dnscms.fields import CommonStreamField
from venues.models import VenuePage
@ -117,6 +118,36 @@ class EventCategory(models.Model):
return self.name
class EventOrganizerLink(Orderable):
event = ParentalKey(
"events.EventPage", on_delete=models.CASCADE, related_name="organizer_links"
)
organizer = models.ForeignKey(
"events.EventOrganizer",
on_delete=models.PROTECT,
related_name="organized_events",
help_text="",
)
panels = [FieldPanel("organizer", heading="", help_text="")]
graphql_fields = [
GraphQLForeignKey("organizer", "events.EventOrganizer"),
]
def __str__(self):
return f"{self.organizer.name}"
class Meta:
verbose_name = "Arrangør"
verbose_name_plural = "Arrangører"
constraints = [
UniqueConstraint(
"event", "organizer", name="event_organizer_link_event_organizer_unique"
)
]
@register_snippet
@register_query_field("eventOrganizer", "eventOrganizers")
class EventOrganizer(ClusterableModel):
@ -137,12 +168,39 @@ class EventOrganizer(ClusterableModel):
blank=True,
on_delete=models.PROTECT,
related_name="organizers",
help_text="Om en samfundsforening eller et utvalg står bak, velg det her.",
)
external_url = models.URLField(
blank=True,
max_length=512,
help_text="Lenke til nettstedet til ekstern arrangør",
)
panels = [
TitleFieldPanel("name"),
FieldPanel("slug"),
PageChooserPanel("association", ["associations.AssociationPage"]),
FieldPanel(
"association",
widget=AssociationChooserWidget(linked_fields={"association": "#id_association"}),
heading="Intern arrangør",
),
MultiFieldPanel(
heading="Ekstern arrangør",
children=[
FieldPanel(
"external_url",
heading="Nettsted",
help_text="La denne stå tom om arrangøren finnes i lista over.",
),
],
),
]
graphql_fields = [
GraphQLString("name"),
GraphQLForeignKey("association", "associations.AssociationPage", required=False),
GraphQLString("external_url"),
]
class Meta:
@ -191,9 +249,8 @@ class EventPage(Page):
blank=True,
)
organizers = ParentalManyToManyField(
"events.EventOrganizer",
blank=True,
organizers = models.ManyToManyField(
"events.EventOrganizer", through="events.EventOrganizerLink"
)
PIG_CHOICES = [
@ -251,7 +308,17 @@ class EventPage(Page):
FieldPanel("featured_image"),
FieldPanel("body"),
FieldPanel("categories", widget=forms.CheckboxSelectMultiple),
FieldPanel("organizers", widget=forms.SelectMultiple),
MultiFieldPanel(
heading="Arrangører",
children=[
HelpPanel(
content=("Hvem står bak arrangementet?"),
),
MultipleChooserPanel(
"organizer_links", chooser_field_name="organizer", min_num=1, label="Arrangør"
),
],
),
FieldPanel("pig", heading="Gris"),
FieldPanel(
"facebook_url",
@ -309,6 +376,16 @@ class EventPage(Page):
def clean(self):
super().clean()
# remove duped organizers based on name
organizers = [x.organizer.name for x in self.organizer_links.all()]
if len(organizers) != len(set(organizers)):
seen_organizers = set()
for link in self.organizer_links.all():
if link.organizer.name in seen_organizers:
self.organizer_links.remove(link)
else:
seen_organizers.add(link.organizer.name)
# if the event is free, all specific pricing is unset
if self.free:
self.price_regular = None

View File

@ -0,0 +1,15 @@
from wagtail.admin.viewsets.chooser import ChooserViewSet
class EventOrganizerChooserViewSet(ChooserViewSet):
model = "events.EventOrganizer"
icon = "group"
per_page = 30
page_title = "Choose organizers"
choose_one_text = "Choose an organizer"
choose_another_text = "Choose another organizer"
edit_item_text = "Edit this organizer"
form_fields = ["name", "association", "external_url"]
event_organizer_chooser_viewset = EventOrganizerChooserViewSet("event_organizer_chooser")

View File

@ -0,0 +1,8 @@
from wagtail import hooks
from .views import event_organizer_chooser_viewset
@hooks.register("register_admin_viewset")
def register_viewset():
return event_organizer_chooser_viewset

3
dnscms/events/widgets.py Normal file
View File

@ -0,0 +1,3 @@
from .views import event_organizer_chooser_viewset
EventOrganizerChooserWidget = event_organizer_chooser_viewset.widget_class