alpinesmuseum-public/cms/models.py

191 lines
6.4 KiB
Python
Raw Normal View History

2022-09-23 02:08:37 +00:00
from datetime import date
from decimal import Decimal
from itertools import chain
from catalog.models import Comment, SiteConfig
from django import forms
from django.db import models
from django.utils.translation import gettext_lazy as _
from modelcluster.fields import ParentalKey
from wagtail.admin.edit_handlers import (FieldPanel, InlinePanel,StreamFieldPanel)
from wagtail.contrib.forms.forms import FormBuilder
from wagtail.contrib.forms.models import (FORM_FIELD_CHOICES, AbstractForm,
AbstractFormField)
from wagtail.core import blocks
from wagtail.core.fields import RichTextField, StreamField
from wagtail.core.models import Page
from wagtail.embeds.blocks import EmbedBlock
from .blocks import ImageListBlock, ModalBlock, YellowStripBlock, NewsletterBlock
from .utils import get_current_site, TranslatedField, get_language_codes
class CustomFormBuilder(FormBuilder):
def __init__(self, fields):
super().__init__(fields)
def create_file_field(self, field, options):
return forms.FileField(**options)
def create_multiselect_field(self, field, options):
return super().create_checkboxes_field(field, options)
class CustomPageMixin(Page):
class Meta:
abstract = True
menu_link_text = models.CharField(
max_length=255, blank=True
)
promote_panels = Page.promote_panels + [
FieldPanel("menu_link_text")
]
preview_modes = []
class ImageGallery(Page):
template = "pages/image_gallery.html"
preview_modes = []
class InfoPage(CustomPageMixin):
template = "pages/info.html"
body = StreamField([
("header_video", EmbedBlock()),
("paragraph", blocks.RichTextBlock()),
("medium_text", blocks.RichTextBlock()),
("h1_big_text", blocks.TextBlock()),
("image_list", ImageListBlock()),
("yellow_strip", YellowStripBlock())
])
footer = StreamField([("modal", ModalBlock())], blank=True)
newsletter_strip = StreamField([("Newletter", NewsletterBlock())], max_num=1, blank=True)
content_panels = CustomPageMixin.content_panels + [
StreamFieldPanel("body"),
StreamFieldPanel("footer"),
StreamFieldPanel("newsletter_strip")
]
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
site_config = SiteConfig.objects.get(site=get_current_site(request))
context["site_config"] = site_config
return context
class GenericPage(CustomPageMixin):
template = "pages/generic.html"
body = StreamField([
("paragraph", blocks.RichTextBlock()),
("medium_text", blocks.RichTextBlock()),
("h1_big_text", blocks.TextBlock()),
("image_list", ImageListBlock()),
("modal", ModalBlock())
])
content_panels = CustomPageMixin.content_panels + [
StreamFieldPanel("body")
]
class CustomAbstractForm(CustomPageMixin, AbstractForm):
class Meta:
abstract = True
TRANSLATED_FIELDS = {
'help_text': models.CharField(verbose_name=_('help text'), max_length=255, blank=True),
'choices': models.TextField(
verbose_name='choices',
blank=True,
help_text=_('Comma separated list of choices. Only applicable in checkboxes, radio and dropdown.')
)
}
class ContributeField(AbstractFormField):
CHOICES = FORM_FIELD_CHOICES + (('file', 'Upload File'),)
page = ParentalKey("ContributePage", on_delete=models.CASCADE, related_name="form_fields")
field_type = models.CharField(
verbose_name='field type',
max_length=16,
choices=CHOICES
)
choices = TranslatedField("choices")
help_text = TranslatedField("help_text")
AbstractFormField.panels = [
field
for field in AbstractFormField.panels
if field.field_name not in TRANSLATED_FIELDS.keys()
]
panels = AbstractFormField.panels + list(
chain.from_iterable([
[
FieldPanel(f"{field}_{language_code}")
for language_code in get_language_codes()
]
for field in TRANSLATED_FIELDS.keys()
])
)
for field in TRANSLATED_FIELDS:
for language_code in get_language_codes():
_, path, args, kwargs = TRANSLATED_FIELDS[field].deconstruct()
kwargs['verbose_name'] = f"{kwargs['verbose_name']} ({language_code})"
ContributeField.add_to_class(
f"{field}_{language_code}",
TRANSLATED_FIELDS[field].__class__(*args, **kwargs)
)
class ContributePage(CustomAbstractForm):
template = "pages/contribute.html"
landing_page_template = "pages/contribute_landing.html"
form_builder = CustomFormBuilder
details = RichTextField(blank=True)
bottom_details = StreamField([
("paragraph", blocks.RichTextBlock()),
("medium_text", blocks.RichTextBlock()),
("h1_big_text", blocks.TextBlock()),
("image_list", ImageListBlock()),
("modal", ModalBlock())
], blank=True)
content_panels = CustomAbstractForm.content_panels + [
FieldPanel("details", classname="full"),
InlinePanel("form_fields", label="Form Fields"),
FieldPanel("bottom_details", classname="full")
]
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
site_config = SiteConfig.objects.get(site=get_current_site(request))
context["site_config"] = site_config
return context
def process_form_submission(self, form):
"""
Processes the form submission, if an Image upload is found, pull out the
files data, create an actual Wgtail Image and reference its ID only in the
stored form response.
"""
cleaned_data = form.cleaned_data
matching_fields = map(lambda f: f.name, Comment._meta.get_fields()) & cleaned_data.keys()
non_matching_fields = cleaned_data.keys() - matching_fields
for field in non_matching_fields:
if isinstance(cleaned_data[field], date):
cleaned_data[field] = str(cleaned_data[field])
elif isinstance(cleaned_data[field], Decimal):
cleaned_data[field] = float(cleaned_data[field])
submission = Comment(
**{k: cleaned_data[k] for k in matching_fields},
site=get_current_site(form.page.url),
misc_data={k: cleaned_data[k] for k in non_matching_fields}
)
submission.save()
return submission