from django.db import models from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.utils.translation import ugettext as _ from wagtail.contrib.wagtailroutablepage.models import RoutablePageMixin, route from wagtail.wagtailadmin.edit_handlers import FieldPanel, StreamFieldPanel from wagtail.wagtailcore import blocks from wagtail.wagtailcore.fields import RichTextField, StreamField from wagtail.wagtailcore.models import Page, Orderable from wagtail.wagtailimages.edit_handlers import ImageChooserPanel from wagtail.wagtailimages.blocks import ImageChooserBlock from wagtail.wagtailsnippets.models import register_snippet # Page pouvant afficher des actualités class COFActuIndexMixin: @property def actus(self): actus = COFActuPage.objects.live().order_by('-date_start').descendant_of(self) return actus # Racine du site du COF class COFRootPage(Page, COFActuIndexMixin): introduction = RichTextField("Introduction") content_panels = Page.content_panels + [ FieldPanel('introduction', classname="full"), ] subpage_types = ['COFActuIndexPage', 'COFPage', 'COFDirectoryPage', 'COFUtilPage'] class Meta: verbose_name = "Racine site du COF" verbose_name_plural = "Racines site du COF" # Block iframe class IFrameBlock(blocks.StructBlock): url = blocks.URLBlock("Adresse de la page") height = blocks.CharBlock("Hauteur (en pixels)") class Meta: verbose_name = "Page incluse (iframe, à utiliser avec précaution)" verbose_name_plural = "Pages incluses (iframes, à utiliser avec précaution)" template = "cofcms/iframe_block.html" # Page lambda du site class COFPage(Page): body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('iframe', IFrameBlock()), ]) content_panels = Page.content_panels + [ StreamFieldPanel('body'), ] subpage_types = ['COFDirectoryPage', 'COFPage'] parent_page_types = ['COFPage', 'COFRootPage'] class Meta: verbose_name = "Page normale COF" verbose_name_plural = "Pages normales COF" # Actualités class COFActuIndexPage(Page, COFActuIndexMixin): subpage_types = ['COFActuPage'] parent_page_types = ['COFRootPage'] class Meta: verbose_name = "Index des actualités" verbose_name_plural = "Indexs des actualités" def get_context(self, request): context = super().get_context(request) actus = COFActuPage.objects.live().descendant_of(self).order_by('-date_end') page = request.GET.get('page') paginator = Paginator(actus, 5) try: actus = paginator.page(page) except PageNotAnInteger: actus = paginator.page(1) except EmptyPage: actus = paginator.page(paginator.num_pages) context['actus'] = actus return context class COFActuPage(RoutablePageMixin, Page): chapo = models.TextField("Description rapide", blank=True) body = RichTextField("Contenu") image = models.ForeignKey( 'wagtailimages.Image', verbose_name="Image à la Une", null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) is_event = models.BooleanField("Évènement", default=True, blank=True) date_start = models.DateTimeField("Date et heure de début") date_end = models.DateTimeField("Date et heure de fin", blank=True, default=None, null=True) all_day = models.BooleanField("Toute la journée", default=False, blank=True) content_panels = Page.content_panels + [ ImageChooserPanel('image'), FieldPanel('chapo'), FieldPanel('body', classname="full"), FieldPanel("is_event"), FieldPanel("date_start"), FieldPanel("date_end"), FieldPanel("all_day"), ] subpage_types = [] parent_page_types = ['COFActuIndexPage'] class Meta: verbose_name = "Actualité" verbose_name_plural = "Actualités" # Annuaires (Clubs, partenaires, bonnes adresses) class COFDirectoryPage(Page): introduction = RichTextField("Introduction") alphabetique = models.BooleanField("Tri par ordre alphabétique ?", default=True, blank=True) content_panels = Page.content_panels + [ FieldPanel('introduction'), FieldPanel('alphabetique'), ] subpage_types = ['COFActuPage', 'COFDirectoryEntryPage'] parent_page_types = ['COFRootPage', 'COFPage'] @property def entries(self): entries = COFDirectoryEntryPage.objects.live()\ .descendant_of(self) if self.alphabetique: entries = entries.order_by("title") return entries class Meta: verbose_name = "Annuaire (clubs, partenaires, bons plans...)" verbose_name_plural = "Annuaires" class COFDirectoryEntryPage(Page, Orderable): body = RichTextField("Description") links = StreamField([ ('lien', blocks.StructBlock([ ('url', blocks.URLBlock(required=True)), ('texte', blocks.CharBlock()), ])), ('contact', blocks.StructBlock([ ('email', blocks.EmailBlock(required=True)), ('texte', blocks.CharBlock()), ])), ]) image = models.ForeignKey( 'wagtailimages.Image', verbose_name="Image", null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) content_panels = Page.content_panels + [ ImageChooserPanel('image'), FieldPanel('body', classname="full"), StreamFieldPanel("links"), ] subpage_types = [] parent_page_types = ['COFDirectoryPage'] class Meta: verbose_name = "Entrée d'annuaire" verbose_name_plural = "Entrées d'annuaire" # Pour le calendrier, ne doit pas être pris par ModelTranslation class COFUtilPage(RoutablePageMixin, Page): # Mini calendrier @route(r'^calendar/(\d+)/(\d+)/$') def calendar(self, request, year, month): from .views import raw_calendar_view return raw_calendar_view(request, int(year), int(month)) def debugged_get_url(self, request): parent = COFRootPage.objects.parent_of(self).live().first() burl = parent.relative_url(request.site) return burl + self.slug class Meta: verbose_name = "Page utilitaire" verbose_name_plural = "Pages utilitaires"