nord
clone your own copy | download snapshot

Snapshots | iceberg

Inside this repository

models.py
text/x-python

Download raw (8.9 KB)

from django.db import models

# Create your models here.
from django.db import models

from modelcluster.fields import ParentalKey
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase

from wagtail.core.models import Page, Orderable
from wagtail.core.fields import RichTextField, StreamField
from wagtail.core import blocks
from wagtail.images.blocks import ImageChooserBlock
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel, StreamFieldPanel, MultiFieldPanel, FieldRowPanel
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.search import index

from wagtail.snippets.blocks import SnippetChooserBlock
from wagtail.snippets.edit_handlers import SnippetChooserPanel
from wagtail.snippets.models import register_snippet

RICHTEXTFIELD_INLINE_FEATURE_SET = ['bold', 'italic', 'superscript', 'link', 'document_link']

class HeadingBlock(blocks.CharBlock):
  class Meta:
    template = 'projects/blocks/heading.html'
    classname = 'full title'
    icon = 'title'


def get_project_datablock_choices():
  return [(0, 'Status'),
    (1, 'Procedure'),
    (2, 'Area'),
    (3, 'Budget'),
    (4, 'Team: Architecture'),
    (5, 'Team: Public space'),
    (6, 'Team: Landscape'),
    (7, 'Team: Structure Ir'),
    (8, 'Team: HVAC Ir'),
    (9, 'Team: Energy performance '),
    (10, 'Team: Acoustic '),
    (11, 'Team: Graphic Design'),
    (12, 'Team: Artist collaborator'),
    (13, 'Team: BIM manager'),
    (14, 'Team: Participation'),
    (15, 'Team: Design'),
    (16, 'Sub-contractor: Architecture'),
    (17, 'Sub-contractor: Public space'),
    (18, 'Sub-contractor: Landscape'),
    (19, 'Sub-contractor: Structure Ir'),
    (20, 'Sub-contractor: HVAC Ir'),
    (21, 'Sub-contractor: Energy performance '),
    (22, 'Sub-contractor: Acoustic '),
    (23, 'Sub-contractor: Graphic Design'),
    (24, 'Sub-contractor: Artist collaborator'),
    (25, 'Sub-contractor: BIM manager'),
    (26, 'Sub-contractor: Participation'),
    (27, 'Sub-contractor: Design'),
    (28, 'Built area'),
    (29, 'Renovated area'),
    (30, 'Surroundings area'),
    (31, 'Initial budget'),
    (32, 'Adjudication budget'),
    (33, 'Final budget'),
    (34, 'Study start'),
    (35, 'Expected delivery date'),
    (36, 'Delivery date')]


def get_project_gallery_layout_choices ():
  return [
    (0, 'Inline scroll'),
    (1, '2-up grid'),
    (2, '3-up grid'),
    (4, '4-up grid')]


def get_project_gallery_layout_names ():
  return [
    (0, 'inline'),
    (1, 'grid-2'),
    (2, 'grid-3'),
    (4, 'grid-4')]


class DataBlock(blocks.StructBlock):
  name = blocks.ChoiceBlock(choices=get_project_datablock_choices, classname='field-col col6', form_classname='field-col col6')
  value = blocks.CharBlock(classname='field-col col6', form_classname='field-col col6')

  class Meta:
    icon = 'horizontalrule'
    form_classname = 'field_row'
    template = 'projects/blocks/project-stream-datablock-datarow.html'


@register_snippet
class Quote(index.Indexed, models.Model):
  quote = RichTextField(features=['bold', 'italic'])
  attribution = models.CharField(blank=True, max_length=250)

  panels = [
    FieldPanel('quote'),
    FieldPanel('attribution')
  ]

  search_fields = [
    index.SearchField('quote'),
    index.SearchField('attribution')
  ]

  def __str__ (self):
    return self.quote

@register_snippet
class Image (index.Indexed, models.Model):
  image =  models.ForeignKey(
    'wagtailimages.Image',
    on_delete=models.PROTECT,
    related_name='+'
  )

  caption = RichTextField(features=RICHTEXTFIELD_INLINE_FEATURE_SET, blank=True)

  panels = [
    ImageChooserPanel('image'),
    FieldPanel('caption')
  ]

  search_fields = [
    index.SearchField('caption')
  ]


class ProjectBaseBlock (blocks.StructBlock):
  name = blocks.CharBlock(required=False, help_text="Not displayed, used internally")

  on_home = blocks.BooleanBlock(required=False, help_text="Defines whether this block be displayed on the homepage. Only the first 'homepage' block will be visible.")
  on_list = blocks.BooleanBlock(required=False, help_text="Defines whether this block be displayed on the project listing page.")
  on_detail = blocks.BooleanBlock(required=False, help_text="Defines whether this block will be displayed on the project detail page.")


class ProjectImageBlock (ProjectBaseBlock):
  image = ImageChooserBlock()
  caption = blocks.RichTextBlock(required=False, features=RICHTEXTFIELD_INLINE_FEATURE_SET)

  class Meta:
    template = 'projects/blocks/project-image.html'
    icon = 'image'
    classname= 'collapsible'
    form_classname= 'collapsible'

class ProjectQuoteBlock (ProjectBaseBlock):
  # Todo change quote to RichTextBlock.
  quote = blocks.RichTextBlock(features=RICHTEXTFIELD_INLINE_FEATURE_SET)
  attribution = blocks.RichTextBlock(required=False, features=RICHTEXTFIELD_INLINE_FEATURE_SET)

  class Meta:
    icon = 'openquote'
    template = 'projects/blocks/project-quote.html'
    classname= 'collapsible'
    form_classname= 'collapsible'

class ProjectStreamImageBlock(blocks.StructBlock):
  image = ImageChooserBlock()
  caption = blocks.RichTextBlock(required=False, features=RICHTEXTFIELD_INLINE_FEATURE_SET)

  class Meta:
    icon = 'image'
    template = 'projects/blocks/project-stream-image.html'

class ProjectStreamPlanBlock(ProjectStreamImageBlock):
  pass

class ProjectStreamGallerySpacerBlock(blocks.StaticBlock):
  class Meta:
    template = 'projects/blocks/project-stream-gallery-spacer.html'

class ProjectStreamGalleryBlock(blocks.StructBlock):
  title = blocks.CharBlock(required=False)
  layout = blocks.ChoiceBlock(choices=get_project_gallery_layout_choices)
  images = blocks.StreamBlock([('image', ProjectStreamImageBlock()), ('plan', ProjectStreamPlanBlock()), ('spacer', ProjectStreamGallerySpacerBlock())])
  caption = blocks.RichTextBlock(required=False, features=RICHTEXTFIELD_INLINE_FEATURE_SET)

  class Meta:
    icon = 'folder'
    template = 'projects/blocks/project-stream-gallery.html'

class ProjectStreamDataBlock(blocks.StreamBlock):
  dataheader = blocks.CharBlock(template='projects/blocks/project-stream-datablock-dataheader.html')
  datarow = DataBlock()

  class Meta:
    icon='table'
    template = 'projects/blocks/project-stream-datablock.html'

class ProjectStreamBlock (ProjectBaseBlock):
  body = blocks.StreamBlock([
    ('heading', HeadingBlock()),
    ('text', blocks.RichTextBlock(features=['bold', 'italic', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', 'link', 'document_link', 'embed', 'superscript'])),
    ('quote', blocks.BlockQuoteBlock()),
    ('image', ProjectStreamImageBlock()),
    ('plan', ProjectStreamPlanBlock()),
    ('gallery', ProjectStreamGalleryBlock()),
    ('datablock', ProjectStreamDataBlock()),
  ])

  panels = [ StreamFieldPanel('body') ]

  class Meta: 
    icon = 'doc-full '
    template = 'projects/blocks/project-stream.html'
    label = 'Project Stream Block'
    classname= 'collapsible'
    form_classname= 'collapsible'

class ProjectPage(Page):
  # location = models.CharField(max_length=250, blank=True)

  # title = models.CharField(max_length=250)
  # short_description = RichTextField(features=RICHTEXTFIELD_INLINE_FEATURE_SET)
  created_at = models.DateTimeField(auto_now_add=True)
  updated_at = models.DateTimeField(auto_now=True)

  # coverImage = models.ForeignKey(
  #   'wagtailimages.Image',
  #   null=True,
  #   blank=True,
  #   on_delete=models.SET_NULL,
  #   related_name='+'
  # )

  # snippet = models.ForeignKey(
  #       Project,
  #       on_delete=models.PROTECT,
  #       related_name='+'
  #   )

  body = StreamField([
    ('Image', ProjectImageBlock()),
    ('Quote', ProjectQuoteBlock()),
    ('FreeText', ProjectStreamBlock())
  ])

  # body = StreamField([
  #   ('Projectsnippet', SnippetChooserBlock(Project))
  #   # ('heading', HeadingBlock()),
  #   # ('paragraph', blocks.RichTextBlock()),
  #   # ('quote', blocks.BlockQuoteBlock()),
  #   # ('datablock', blocks.StreamBlock([
  #   #   ('datarow', DataBlock()),
  #   #   ('dataheader', blocks.CharBlock()
  #   # )], icon='table', template='projects/blocks/datablock.html')),
  #   # ('plan', ImageChooserBlock()),
  #   # ('picture', ImageChooserBlock()),
  #   # ('gallery', blocks.StreamBlock([
  #   #   ('plan', ImageChooserBlock()),
  #   #   ('picture', ImageChooserBlock())  
  #   # ]))
  # ])
  
  search_fields = Page.search_fields + [
    index.SearchField('short_description')
  ]

  content_panels = Page.content_panels + [
    # FieldPanel('short_description'),
    # ImageChooserPanel('coverImage'),
    StreamFieldPanel('body')
  ]

  parent_page_types = ['projects.ProjectIndexPage']
  subpage_types = []


class ProjectIndexPage(Page):
  def get_context(self, request):
    context = super().get_context(request)  
    projectpages = self.get_children().live().order_by('-first_published_at')
    context['projectpages'] = projectpages
    return context
  
  parent_page_types = ['home.HomePage']
  subpage_types = ['projects.ProjectPage']