Files
neuf-www/dnscms/events/models.py

437 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django import forms
from django.db import models
from django.utils.translation import gettext_lazy as _
from grapple.helpers import register_query_field
from grapple.models import (
GraphQLBoolean,
GraphQLCollection,
GraphQLForeignKey,
GraphQLImage,
GraphQLInt,
GraphQLStreamfield,
GraphQLString,
)
from modelcluster.fields import ParentalKey, ParentalManyToManyField
from modelcluster.models import ClusterableModel
from wagtail import blocks
from wagtail.admin.panels import (
FieldPanel,
FieldRowPanel,
HelpPanel,
InlinePanel,
MultiFieldPanel,
PageChooserPanel,
TitleFieldPanel,
)
from wagtail.contrib.settings.models import (
BaseSiteSetting,
register_setting,
)
from wagtail.fields import StreamField
from wagtail.images.blocks import ImageChooserBlock
from wagtail.models import Orderable, Page
from wagtail.snippets.models import register_snippet
from venues.models import VenuePage
class EventIndex(Page):
# there can only be one event index page
max_count = 1
subpage_types = ["events.EventPage"]
graphql_fields = []
@register_snippet
@register_query_field("eventCategory", "eventCategories")
class EventCategory(models.Model):
name = models.CharField(
max_length=100,
null=False,
blank=False,
)
slug = models.SlugField(
verbose_name=_("slug"),
max_length=255,
help_text=_("The name of the category as it will appear in URLs."),
)
show_in_filters = models.BooleanField(
default=False, help_text="Skal denne kategorien være mulig å filtrere på i programmet?"
)
panels = [TitleFieldPanel("name"), FieldPanel("slug"), FieldPanel("show_in_filters")]
graphql_fields = [
GraphQLString("name", required=True),
GraphQLString("slug", required=True),
GraphQLBoolean("show_in_filters", required=True),
]
class Meta:
verbose_name = "Event category"
verbose_name_plural = "Event categories"
ordering = ["name"]
def __str__(self):
return self.name
@register_snippet
@register_query_field("eventOrganizer", "eventOrganizers")
class EventOrganizer(ClusterableModel):
name = models.CharField(
max_length=100,
null=False,
blank=False,
)
slug = models.SlugField(
verbose_name=_("slug"),
max_length=255,
help_text=_("The name of the organizer as it will appear in URLs."),
)
association = models.ForeignKey(
"associations.AssociationPage",
null=True,
blank=True,
on_delete=models.PROTECT,
related_name="organizers",
)
panels = [
TitleFieldPanel("name"),
FieldPanel("slug"),
PageChooserPanel("association", ["associations.AssociationPage"]),
]
class Meta:
verbose_name = "Event organizer"
verbose_name_plural = "Event organizers"
ordering = ["name"]
def __str__(self):
return self.name
@register_setting
# @register_query_field("eventPromoSettings")
class EventPromoSettings(ClusterableModel, BaseSiteSetting):
panels = [InlinePanel("featured_events", heading="Fremhevede arrangementer")]
graphql_fields = [
GraphQLCollection(
GraphQLForeignKey,
"featured_events",
"events.EventPage",
source="featured_events.event",
required=True,
item_required=True,
),
]
class FeaturedEventsOrderable(ClusterableModel):
event_promo_settings = ParentalKey("events.EventPromoSettings", related_name="featured_events")
event = models.ForeignKey(
"events.EventPage",
on_delete=models.CASCADE,
)
panels = [
PageChooserPanel("event", "events.EventPage"),
]
class EventPage(Page):
# no children
subpage_types = []
parent_page_types = ["events.EventIndex"]
# should not be able to be shown in menus
show_in_menus = False
# inherited from Page:
# title = text
# slug = text (in promote panel)
# content_type = points to this model
# live = bool
# owner = page creator
# first_published_at = datetime
# last_published_at = datetime
# seo_title: text (in promote panel)
# search_description: text (in promote panel)
featured_image = models.ForeignKey(
"wagtailimages.Image",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
help_text=(
"Velg et bilde til bruk i programmet og andre visningsflater. "
"Bør være et bilde eller en illustrasjon uten tekst "
" ikke gjenbruk et Facebook-cover ukritisk!"
),
)
body = StreamField(
[
("paragraph", blocks.RichTextBlock()),
("image", ImageChooserBlock()),
]
)
categories = ParentalManyToManyField(
"events.EventCategory",
blank=True,
)
organizers = ParentalManyToManyField(
"events.EventOrganizer",
blank=True,
)
ticket_url = models.URLField(
blank=True,
max_length=512,
help_text="Lenke direkte til billettkjøp, f.eks. TicketCo eller Ticketmaster",
)
facebook_url = models.URLField(
blank=True,
max_length=512,
help_text="Lenke direkte til arrangementet på Facebook",
)
# "event_organizers": [390, 322],
price_regular = models.IntegerField(null=True, blank=True)
price_student = models.IntegerField(null=True, blank=True)
price_member = models.IntegerField(null=True, blank=True)
ticket_panels = [
FieldPanel("ticket_url", heading="Billettkjøpslenke"),
FieldRowPanel(
children=[
FieldPanel("price_regular", heading="Ordinær pris"),
FieldPanel("price_student", heading="Pris for studenter"),
FieldPanel("price_member", heading="Pris for medlemmer av DNS"),
],
help_text="",
),
HelpPanel(content="La alle prisfeltene stå tomme om arrangementet er gratis."),
]
content_panels = Page.content_panels + [
FieldPanel("featured_image"),
FieldPanel("body"),
FieldPanel("categories", widget=forms.CheckboxSelectMultiple),
FieldPanel("organizers", widget=forms.SelectMultiple),
FieldPanel(
"facebook_url",
heading="Facebook-lenke",
help_text="Lenke direkte til arrangementet på Facebook.",
),
MultiFieldPanel(
heading="Priser og billettkjøp",
children=ticket_panels,
),
MultiFieldPanel(
children=[
HelpPanel(
heading="Forekomster",
content=(
"Om arrangementet går over flere dager, "
"legg inn hver dag som en egen forekomst."
),
),
InlinePanel("occurrences", min_num=1),
]
),
]
graphql_fields = [
GraphQLImage("featured_image"),
GraphQLStreamfield("body"),
GraphQLString("ticket_url"),
GraphQLString("facebook_url"),
GraphQLInt("price_regular"),
GraphQLInt("price_student"),
GraphQLInt("price_member"),
GraphQLCollection(
GraphQLForeignKey,
"categories",
"events.EventCategory",
required=True,
item_required=True,
),
GraphQLCollection(
GraphQLForeignKey,
"occurrences",
"events.EventOccurrence",
required=True,
item_required=True,
),
GraphQLCollection(
GraphQLForeignKey,
"organizers",
"events.EventOrganizer",
required=True,
item_required=True,
),
]
class EventOccurrence(Orderable):
event = ParentalKey(EventPage, on_delete=models.CASCADE, related_name="occurrences")
start = models.DateTimeField()
end = models.DateTimeField(null=True, blank=True)
venue = models.ForeignKey(
VenuePage, on_delete=models.PROTECT, related_name="event_occurrences"
)
panels = [
FieldRowPanel(
children=[
FieldPanel("start", heading="Start"),
FieldPanel("end", heading="Slutt"),
],
),
FieldPanel("venue", heading="Lokale"),
]
graphql_fields = [
GraphQLString("start", required=True),
GraphQLString("end"),
GraphQLForeignKey("venue", "venues.VenuePage"),
]
def __str__(self):
return f"{self.start}--{self.end}"
class Meta:
verbose_name = "Forekomst"
verbose_name_plural = "Forekomster"
sample_legacy_event_json = """
{
"id": 64573,
"date": "2023-12-27T11:28:34",
"date_gmt": "2023-12-27T10:28:34",
"guid": {
"rendered": "https://studentersamfundet.no/?post_type=event&p=64573"
},
"modified": "2023-12-27T11:44:11",
"modified_gmt": "2023-12-27T10:44:11",
"slug": "quiz-147-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-3-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-3-2-2-2-2-2-2-2-2-2-2-2-2-2",
"status": "publish",
"type": "event",
"link": "https://studentersamfundet.no/arrangement/quiz-147-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-3-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-3-2-2-2-2-2-2-2-2-2-2-2-2-2/",
"title": {
"rendered": "QUIZ",
"decoded": "QUIZ"
},
"content": {
"rendered": "\n<p>Det Norske Studentersamfund inviterer til quiz hver tirsdag kl. 19:00.</p>\n\n\n\n<p>Vi serverer 50 spørsmål som kan spenne seg fra one hit wonders fra 80-tallet, universets uendelighet, dyrelivets merkverdigheter og mye, mye mer!</p>\n\n\n\n<p>Quiz på Chateau Neuf er åpent for alle. Vinnere og &#8220;lucky losers&#8221; vil bli utnevnt hver kveld. Lag som er over seks personer er tillatt, men da trekkes dere for ett poeng per deltaker per runde.</p>\n\n\n\n<p>For de som ønsker å være med på sammenlagtkonkurransen for høsten vil den regnes ut for de tolv beste prestasjonene laget leverer. Så det vil fremdeles være god sjanse for å vinne sammenlagt selv dere må droppe en quiz eller to for eksamener eller andre forpliktelser.</p>\n\n\n\n<p>Velkommen quizglade mennesker!</p>\n\n\n\n<p>Gratis inngang!</p>\n",
"protected": false
},
"excerpt": {
"rendered": "<p>Det Norske Studentersamfund inviterer til quiz hver tirsdag kl. 19:00. Vi serverer 50 spørsmål som kan spenne seg fra one hit wonders fra 80-tallet, universets uendelighet, dyrelivets merkverdigheter og mye, mye mer! Quiz på Chateau Neuf er åpent for alle. Vinnere og &#8220;lucky losers&#8221; vil bli utnevnt hver kveld. Lag som er over seks personer [&hellip;]</p>\n",
"protected": false
},
"author": 2150,
"featured_media": 64585,
"template": "",
"meta": [],
"event_types": [13],
"event_organizers": [390, 322],
"facebook_url": "https://fb.me/e/2RDR5pZdr",
"ticket_url": "",
"price_regular": "",
"price_member": "",
"start_time": "2024-05-07T17:00:00+00:00",
"end_time": "2024-05-07T20:00:00+00:00",
"venue": "Glassbaren",
"venue_id": "55063",
"thumbnail": {
"thumbnail": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-150x150.png",
"medium": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-300x169.png",
"medium_large": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-768x433.png",
"large": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-1280x720.png",
"1536x1536": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-1536x865.png",
"2048x2048": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1.png",
"four-column": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-393x342.png",
"six-column": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-608x342.png",
"extra-large": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-1600x901.png",
"newsletter-half": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-320x190.png",
"newsletter-third": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-213x126.png",
"featured": "https://studentersamfundet.no/wp/wp-content/uploads/2023/12/quiz-header-1-1200x480.png"
},
"_links": {
"self": [
{
"href": "https://studentersamfundet.no/wp-json/wp/v2/events/64573"
}
],
"collection": [
{
"href": "https://studentersamfundet.no/wp-json/wp/v2/events"
}
],
"about": [
{
"href": "https://studentersamfundet.no/wp-json/wp/v2/types/event"
}
],
"author": [
{
"embeddable": true,
"href": "https://studentersamfundet.no/wp-json/wp/v2/users/2150"
}
],
"version-history": [
{
"count": 1,
"href": "https://studentersamfundet.no/wp-json/wp/v2/events/64573/revisions"
}
],
"predecessor-version": [
{
"id": 64574,
"href": "https://studentersamfundet.no/wp-json/wp/v2/events/64573/revisions/64574"
}
],
"wp:featuredmedia": [
{
"embeddable": true,
"href": "https://studentersamfundet.no/wp-json/wp/v2/media/64585"
}
],
"wp:attachment": [
{
"href": "https://studentersamfundet.no/wp-json/wp/v2/media?parent=64573"
}
],
"wp:term": [
{
"taxonomy": "event_type",
"embeddable": true,
"href": "https://studentersamfundet.no/wp-json/wp/v2/event_types?post=64573"
},
{
"taxonomy": "event_organizer",
"embeddable": true,
"href": "https://studentersamfundet.no/wp-json/wp/v2/event_organizers?post=64573"
}
],
"curies": [
{
"name": "wp",
"href": "https://api.w.org/{rel}",
"templated": true
}
]
}
}
"""